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

我正在将一个 C 库移植到 Go 中,一个 C 函数(带有 varargs)是这样定义的:

curl_easy_setopt(CURL *curl, CURLoption option, ...);

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

curl_wrapper_easy_setopt_str(CURL *curl, CURLoption option, char* param);
curl_wrapper_easy_setopt_long(CURL *curl, CURLoption option, long param);

如果我像这样定义 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)))
}

Go 编译器抱怨道:

*Easy·SetOption redeclared in this block

那么 Go 支持函数(方法)重载吗,还是这个错误意味着其他什么?

123437 次浏览

不,没有。

参见 语言常见问题解答,特别是关于 超载的章节。

如果不需要进行类型匹配,则简化了方法分派。其他语言的经验告诉我们,使用同名但不同签名的各种方法有时是有用的,但在实践中也可能是混乱和脆弱的。在 Go 的类型系统中,仅通过名称匹配并要求类型的一致性是一个主要的简化决策。

更新: 2016-04-07

虽然 Go 仍然没有重载函数(可能永远也不会) ,但重载最有用的特性,即使用可选参数调用函数并推断那些被忽略的函数的默认值,也可以使用后来添加的可变参数函数进行模拟。但这是在失去类型检查的情况下进行的。

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

根据这个,它不是: http://golang.org/doc/go_for_cpp_programmers.html

概念差异部分,它写道:

Go 不支持函数重载,也不支持用户定义的操作符。

尽管这个问题已经很老了,但我仍然想说的是,有一种方法可以实现类似于重载函数的功能。虽然它可能不会使代码如此容易阅读。

假设你想让函数 Test()超载:

func Test(a int) {
println(a);
}
func Test(a int, b string) {
println(a);
println(b);
}

上面的代码将导致错误。但是,如果您将第一个 Test()重定义为 Test1(),将第二个重定义为 Test2(),并使用 go 的 ...定义一个新函数 Test(),那么您就能够以函数重载的方式调用该函数 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");
}

产出:

1
1
aaa

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

不,Go 没有超载。

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

正如 Lawrence Dol 提到的,你可以使用一个可变参数函数,而不需要进行类型检查。

您最好的选择是使用 非专利药类型约束,它们是在 < a href = “ https://Go.dev/blog/go1.18”rel = “ nofollow norefrer”> 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))
}