在Go语言中,无法进行函数重载。

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

Overloading a function in go doesn't work

问题

我有一个函数,目前没有接收一个布尔参数,但是调用另一个函数时使用了一个硬编码的布尔值。我们需要移除硬编码的调用,并允许传递一个布尔值。

我最初想尝试一些默认参数 - 我的谷歌搜索结果显示,Go 显然不支持可选(或默认)参数。

所以我想尝试函数重载。

我在 Reddit 上找到了这个帖子,它说从 1.7.3 版本开始可以使用一个特殊的指令来实现函数重载:
https://www.reddit.com/r/golang/comments/5c57kg/when_did_function_overloading_get_slipped_in/
我正在使用 1.8 版本,但是我仍然无法让它工作。

我甚至不确定我是否被允许使用那个指令,但我猜想立即更改函数签名可能是危险的,因为我不知道谁在使用这个函数...

无论如何 - 即使使用了 //+overloaded,它也没有起作用。

在 Go 中是否有任何“特殊”的方法或模式来解决这个问题?

//一些注释
//+overloaded
func (self *RemoteSystem) Apply(rpath, lpath string, dynamic bool) error {
   result, err := anotherFunc(rpath, dynamic)  
}

//一些注释
//+overloaded
func (self *RemoteSystem) Apply(rpath, lpath string ) error {
  //在这个函数中调用了 anotherFunc,并且 dynamic 被硬编码为 true
   //result, err := anotherFunc(rpath, true)
  return self.Apply(rpath, lpath, true)
}

当我运行我的测试时,我得到了以下错误(原路径部分已省略):

调用 self.Apply 时参数过多
	已有 (string, string, bool)
	期望 (string, string)
../remotesystem.go:178: (*RemoteSystem).Apply 在此块中重新声明
	之前的声明在 ../remotesystem.go:185 中
英文:

I have a function which currently doesn't receive a bool parameter, but then calls another function with a hardcoded bool. We need to remove the hardcoded call and allow a bool to be passed.

I first thought I could try some default parameter - my google searches resulted in that Go apparently doesn't support optional (resp. default) parameter.

So I thought I'd try function overloading.

I found this thread on reddit, which says that it works with a special directive since version 1.7.3:
https://www.reddit.com/r/golang/comments/5c57kg/when_did_function_overloading_get_slipped_in/
I am using 1.8, and still I couldn't get it to work.

I am not even sure I may be allowed to use that directive, but I was speculating that changing the function signature right away may be dangerous as I don't know who uses the function...

Anyway - even with //+overloaded it didn't work

Is there any "idiosyncratic" way or pattern to solve this problem in Go?

//some comment
//+overloaded
func (self *RemoteSystem) Apply(rpath, lpath string, dynamic bool) error {
   result, err := anotherFunc(rpath, dynamic)  
}

//some comment
//+overloaded
func (self *RemoteSystem) Apply(rpath, lpath string ) error {
  //in this function anotherFunc was being called, and dynamic is hardcoded to true
   //result, err := anotherFunc(rpath, true)
  return self.Apply(rpath, lpath, true)
}

When I run my test, I get (forgive me for omitting part of the real path to file):

too many arguments in call to self.Apply
	have (string, string, bool)
	want (string, string)
../remotesystem.go:178: (*RemoteSystem).Apply redeclared in this block
	previous declaration at ../remotesystem.go:185

答案1

得分: 6

在Go语言中,没有提供函数重载的功能。而是通过在函数名中更加明确地表达函数的功能来区分不同的函数。在这个例子中,通常会这样做:

func (self *RemoteSystem) Apply(rpath, lpath string, dynamic bool) error {
    result, err := anotherFunc(rpath, dynamic)  
}

func (self *RemoteSystem) ApplyDynamic(rpath, lpath string ) error {
    // 在这个函数中调用了anotherFunc,并且将dynamic参数硬编码为true
    return self.Apply(rpath, lpath, true)
}

通过函数名,你可以很容易地知道函数之间的区别和原因。

再举一个例子来提供一些背景(有意思的双关)。
我在使用Go语言的go-endpoints编写Google App Engine代码时,根据是否有context对象,日志记录的方式是不同的。我的日志函数最终变成了这样:

func LogViaContext(c context.Context, m string, v ...interface{}) {
    if c != nil {
        appenginelog.Debugf(c, m, v...)
    }
}

func LogViaRequest(r *http.Request, m string, v ...interface{}) {
    if r != nil {
        c := appengine.NewContext(r)
        LogViaContext(c, m, v...)
    }
}

希望以上内容对你有帮助。

英文:

Overloading isn't available in Go. Instead of writing functions with the same name that do different things, it is preferable to be more expressive with what the function does in the function name. In this instance, what would commonly be done is something like this:

func (self *RemoteSystem) Apply(rpath, lpath string, dynamic bool) error {
    result, err := anotherFunc(rpath, dynamic)  
}

func (self *RemoteSystem) ApplyDynamic(rpath, lpath string ) error {
    //in this function anotherFunc was being called, and dynamic is hardcoded to true
    return self.Apply(rpath, lpath, true)
}

Just by the name of the function, you can easily tell what is different and why.

Another example to provide some context (pun intended).
I write a lot of Google App Engine code in Go using go-endpoints. The way to log things is different depending on if you have a context or not. My logging functions ended up like this.

func LogViaContext(c context.Context, m string, v ...interface{}) {
    if c != nil {
	    appenginelog.Debugf(c, m, v...)
    }
}

func LogViaRequest(r *http.Request, m string, v ...interface{}) {
    if r != nil {
	    c := appengine.NewContext(r)
	    LogViaContext(c, m, v...)
    }
}

答案2

得分: 3

Reddit帖子中:

> 通过像素可以看出是Unicode。

Go语言不支持函数重载。但它支持在函数名中使用Unicode字符,这使您可以编写看起来像其他函数名的函数名。

> 第一个是setValue,第二个是setV\u0430lue,也就是setV\xd0\xb0lue(带有CYRILLIC SMALL LETTER A),第三个是setVal\U0001d69ee,也就是setVal\xf0\x9d\x9a\x9ee(带有MATHEMATICAL MONOSPACE SMALL U)。

另请参阅:

英文:

From the Reddit post:

> Unicode. I can tell by the pixels.

Go doesn't support function overloading. But it does support using Unicode characters in function names, which allows you to write function names that look like other function names.

> The first one is setValue, the second one is setV\u0430lue aka setV\xd0\xb0lue (with CYRILLIC SMALL LETTER A) and the third is setVal\U0001d69ee aka setVal\xf0\x9d\x9a\x9ee (with MATHEMATICAL MONOSPACE SMALL U).

See also:

huangapple
  • 本文由 发表于 2017年3月24日 04:12:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/42986096.html
匿名

发表评论

匿名网友

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

确定