Go语言是否有函数/方法重载?

Dar*_*kas 105 go

我正在将一个C库移植到Go.AC函数(使用varargs)定义如下:

curl_easy_setopt(CURL *curl, CURLoption option, ...); 
Run Code Online (Sandbox Code Playgroud)

所以我创建了包装器C函数:

curl_wrapper_easy_setopt_str(CURL *curl, CURLoption option, char* param);
curl_wrapper_easy_setopt_long(CURL *curl, CURLoption option, long param);
Run Code Online (Sandbox Code Playgroud)

如果我在Go中定义函数如下:

func (e *Easy)SetOption(option Option, param string) {
    e.code = Code(C.curl_wrapper_easy_setopt_str(e.curl, C.CURLoption(option), C.CString(param)))
}

func (e *Easy)SetOption(option Option, param long) {
    e.code = Code(C.curl_wrapper_easy_setopt_long(e.curl, C.CURLoption(option), C.long(param)))
}
Run Code Online (Sandbox Code Playgroud)

Go编译器抱怨:

*Easy·SetOption redeclared in this block
Run Code Online (Sandbox Code Playgroud)

Go支持函数(方法)重载也是如此,或者此错误是否意味着其他内容?

Law*_*Dol 137

不,不是的.

请参阅Go语言常见问题解答,特别是有关重载的部分.

如果不需要进行类型匹配,则简化方法调度.使用其他语言的经验告诉我们,使用具有相同名称但签名不同的各种方法偶尔会有用,但在实践中它也可能令人困惑和脆弱.仅根据名称进行匹配并要求在类型中保持一致性是Go类型系统中的主要简化决策.

关于运算符重载,它似乎比绝对要求更方便.如果没有它,事情就更简单了.

更新:2016-04-07

虽然Go仍然没有重载函数(并且可能永远不会),但是重载的最有用的特性,即调用具有可选参数的函数并推断那些省略的函数的默认值可以使用可变参数函数进行模拟,该函数已被添加.但这是因为失去了类型检查.

例如:http://changelog.ca/log/2015/01/30/golang

  • “偶尔有用”?如果我想编写一个对数字求和的函数怎么办?可以接受 int32、int64、uint32、uint64 和字符串两个参数?在不允许重载的 JS 中,我可以使用“number”类型,但在像 Go 这样的严格类型语言中,我必须编写大量名称略有不同的函数:/ (5认同)

Mer*_*rim 17

据此,它没有:http://golang.org/doc/go_for_cpp_programmers.html

概念差异部分,它说:

"Go不支持函数重载,也不支持用户定义的运算符."


小智 16

不,Go 没有重载。

重载会增加编译器的复杂性,并且可能永远不会被添加。

正如 Lawrence Dol 提到的,您可以使用可变参数函数,但代价是不进行类型检查。

最好的选择是使用Go 1.18中添加的泛型类型约束

为了回答 VityaSchel 的问题,在 Lawrence 的答案的评论中,关于如何创建通用求和函数,我在下面写了一个。

https://go.dev/play/p/hRhInhsAJFT


package main

import "fmt"

type Number interface {
  int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64
}

func Sum[number Number](a number, b number) number {
  return a + b
}

func main() {
  var a float64 = 5.1
  var b float64 = 3.2
  println(Sum(a, b))

  var a2 int = 5
  var b2 int = 3
  println(Sum(a2, b2))
}

Run Code Online (Sandbox Code Playgroud)


Sul*_*cid 10

尽管这个问题确实很老了,但我仍然想说的是,有一种方法可以实现接近重载函数的效果。尽管它可能不会使代码变得如此易于阅读。

假设你想重载该函数Test()

func Test(a int) {
    println(a);
}
func Test(a int, b string) {
    println(a);
    println(b);
}
Run Code Online (Sandbox Code Playgroud)

上面的代码会导致错误。但是,如果您重新定义第一个Test()toTest1()和第二个 to Test2(),并Test()使用 go's定义一个新函数...,您将能够Test()以重载的方式调用该函数。代码:

package main;

func Test1(a int) {
    println(a);
}
func Test2(a int, b string) {
    println(a);
    println(b);
}
func Test(a int, bs ...string) {
    if len(bs) == 0 {
        Test1(a);
    } else {
        Test2(a, bs[0]);
    }
}
func main() {
    Test(1);
    Test(1, "aaa");
}
Run Code Online (Sandbox Code Playgroud)

输出:

1
1
aaa
Run Code Online (Sandbox Code Playgroud)

查看更多信息: https: //golangbyexample.com/function-method-overloading-golang/(我不是这篇链接文章的作者,但个人认为它很有用)

  • 这是ugleeee (13认同)