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

huangapple go评论91阅读模式
英文:

Does the Go language have function/method overloading?

问题

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)))
}

英文:

I'm porting a C library to Go. A C function (with varargs) is defined like this:

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

So I created wrapper C functions:

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

If I define function in Go like this:

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)))
}

The Go compiler complains:

*Easy·SetOption redeclared in this block

So does Go support function (method) overloading, or does this error mean something else?

答案1

得分: 233

不,它不支持函数重载。

请参阅Go语言FAQ,特别是关于重载的部分。

如果方法调用不需要进行类型匹配,那么方法调度就会变得简单。我们从其他语言的经验中得知,虽然使用相同名称但具有不同签名的多个方法有时很有用,但在实践中可能会导致混淆和不稳定。在Go的类型系统中,只通过名称匹配并要求类型一致是一个重要的简化决策。

更新日期:2016-04-07

虽然Go仍然不支持函数重载(可能永远不会支持),但最有用的重载特性,即使用可变参数函数模拟调用带有可选参数并推断省略参数的默认值,已经被添加。但这会导致类型检查的丧失。

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

英文:

No it does not.

See the Go Language FAQ, and specifically the section on overloading.

> Method dispatch is simplified if it doesn't need to do type matching as well. Experience with other languages told us that having a variety of methods with the same name but different signatures was occasionally useful but that it could also be confusing and fragile in practice. Matching only by name and requiring consistency in the types was a major simplifying decision in Go's type system.

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.

For example: http://changelog.ca/log/2015/01/30/golang

答案2

得分: 31

根据这个链接,它不支持函数重载和用户定义的运算符。

英文:

According to this, it doesn't: http://golang.org/doc/go_for_cpp_programmers.html

In the Conceptual Differences section, it says:

>Go does not support function overloading and does not support user defined operators.

答案3

得分: 10

即使这个问题很旧,但我仍然想说的是,有一种方法可以实现接近函数重载的效果。尽管这可能会使代码不那么容易阅读。

假设你想要重载函数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/(我不是这篇链接文章的作者,但个人认为它很有用)

英文:

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():

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

The code above will cause error. However if you redefine the first Test() to Test1() and the second to Test2(), and define a new function Test() using go's ..., you would be able to call the function Test() the way it is overloaded.
code:

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");
}

output:

1
1
aaa

see more at: https://golangbyexample.com/function-method-overloading-golang/ (I'm not the author of this linked article but personally consider it useful)

答案4

得分: 9

不,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))
}
英文:

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


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))
}

huangapple
  • 本文由 发表于 2011年8月9日 02:42:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/6986944.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定