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

piok6c0g  于 2022-12-07  发布在  Go
关注(0)|答案(4)|浏览(130)

我正在将一个C库移植到Go上,一个C函数(带有varargs)的定义如下:

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

所以我创建了 Package 器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语言支持函数(方法)重载吗?还是这个错误意味着别的什么?

hi3rlvi2

hi3rlvi21#

不,没有。
请参阅Go Language FAQ,特别是有关重载的部分。
如果不需要进行类型匹配,那么方法的调度就可以得到简化。其他语言的经验告诉我们,让不同的方法具有相同的名称和不同的签名有时候是有用的,但在实践中也可能是混乱和脆弱的。只通过名称进行匹配并要求类型的一致性是Go语言类型系统的一个主要简化决策。
更新日期:2016年4月7日
虽然Go语言还没有重载函数(可能永远不会有),但是重载最有用的特性,即调用一个带有可选参数的函数,并为那些被省略的参数推断出默认值,可以用一个可变参数函数来模拟,这个可变参数函数后来被添加进来了,但是这是以类型检查为代价的。
例如:http://changelog.ca/log/2015/01/30/golang

3df52oht

3df52oht2#

根据这一点,它不会:http://golang.org/doc/go_for_cpp_programmers.html
概念差异部分,它说:
Go语言不支持函数重载,也不支持用户定义的运算符。

vhmi4jdf

vhmi4jdf3#

虽然这个问题已经很老了,但我仍然想说的是,有一种方法可以实现接近重载函数的功能,尽管它可能不会使代码变得那么容易阅读。
如果要重载函数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/(我不是这篇链接文章的作者,但我个人认为它很有用)

iqxoj9l9

iqxoj9l94#

不,Go语言没有重载

多载会增加编译器的复杂性,而且可能永远不会增加。
正如Lawrence Dol提到的,可以使用变量函数,但代价是不进行类型检查。
您最好使用在**Go 1.18中添加的泛型类型约束**
为了回答维蒂亚·谢尔的问题,在劳伦斯的回答的注解中,关于如何构造一个一般的和函数,我在下面写了一个。
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))
}

相关问题