Go语言有函数/方法重载吗?
我正在将 C 库移植到 Go。 C 函数(带有可变参数)的定义如下:
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 是否支持函数(方法)重载,或者这个错误是否意味着其他含义?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不,事实并非如此。
请参阅 Go 语言常见问题解答,特别是关于 重载。
更新:2016-04-07
虽然 Go 仍然没有重载函数(可能永远不会),但重载最有用的功能,即使用可选参数调用函数并推断省略参数的默认值,可以使用可变参数函数进行模拟,此后已添加。但这是在类型检查丢失的情况下实现的。
No it does not.
See the Go Language FAQ, and specifically the section on overloading.
Update: 2016-04-07
While Go still does not have overloaded functions (and probably never will), the most useful feature of overloading, that of calling a function with optional arguments and inferring defaults for those omitted can be simulated using a variadic function, which has since been added. But this comes at the loss of type checking.
据此,它没有: http://golang.org/doc/go_for_cpp_programmers.html
在概念差异部分中,它说:
According to this, it doesn't: http://golang.org/doc/go_for_cpp_programmers.html
In the Conceptual Differences section, it says:
不,Go 没有重载。
重载会增加编译器的复杂性,并且可能永远不会被添加。
正如 Lawrence Dol 提到的,您可以使用可变参数函数,但代价是不进行类型检查。
最好的选择是使用 泛型和类型约束 rel="noreferrer">Go 1.18
为了回答 VityaSchel 的问题,在 Lawrence 的答案的评论中,如何创建一个通用的求和函数,我在下面写了一个。
https://go.dev/play/p/hRhInhsAJFT
No, Go doesn't have overloading.
Overloading adds compiler complexity and will likely never be added.
As Lawrence Dol mentioned, you could use a variadic function at the cost of no type checking.
Your best bet is to use generics and type constraints that were added in Go 1.18
To answer VityaSchel's question, in the comments of Lawrence's answer, of how to make a generic sum function, I've written one below.
https://go.dev/play/p/hRhInhsAJFT
尽管这个问题确实很老了,但我仍然想说的是,有一种方法可以实现接近重载函数的效果。尽管它可能不会使代码变得如此易于阅读。
假设您想重载函数
Test()
:上面的代码将导致错误。但是,如果您将第一个
Test()
重新定义为Test1()
,将第二个重新定义为Test2()
,并定义一个新函数Test()
使用 go 的...
,您将能够以重载的方式调用函数Test()
。代码:
输出:
查看更多信息: https://golangbyexample.com/function-method-overloading -golang/ (我不是这篇链接文章的作者,但我个人认为它很有用)
Even though this question is really old, what I still want to say is that there is a way to acheive something close to overloading functions. Although it may not make the code so easy to read.
Say if you want to overload the funtion
Test()
:The code above will cause error. However if you redefine the first
Test()
toTest1()
and the second toTest2()
, and define a new functionTest()
using go's...
, you would be able to call the functionTest()
the way it is overloaded.code:
output:
see more at: https://golangbyexample.com/function-method-overloading-golang/ (I'm not the author of this linked article but personally consider it useful)
您还可以通过使用
...interface{}
使函数可变参数来实现此目的,这将使param
为 Slice 类型,然后使用
param[0]
去掉其中的第一个值,现在任何类型的参数都是有效的,但以类型检查为代价
You can also do it by making the function variadic using
...interface{}
, this will make theparam
as of type Slice,and then just take off the first value in it using
param[0]
now argument of any type is valid, but at the cost of type checking
正如其他人所说,答案是否定的!
但是 Golang 提供了另一个称为接收器的功能,它可以用来编写接近重载的东西:
基本上,我们使用接收器作为区分函数的一种方式,并且能够<强>对两个不同的函数使用相同的函数名,它们可以具有相同的参数或差异参数,但唯一需要注意的是,您只能使用接收器附加来调用该函数!
我怀疑这种代码是否有用,因为它可能会令人困惑,但尽管如此,它是可能的:)
As others said the answer is No!
But Golang provides another feature called as receivers which can be used to write something close to overloading:
Basically we are using receiver as a way to differentiate the functions and are able to use same function name for two different functions which can have same args or diff args, but the only caveat is that you can invoke the function only with receiver as its attached to it !
I doubt this kind of code could be useful as it can be confusing, but nevertheless its possible :)