Go可以有可选参数吗?或者我可以定义两个不同的函数,具有相同的名称和不同数量的参数?
当前回答
Go没有可选参数,也不支持方法重载:
方法调度被简化了 不需要做类型匹配 好。有使用其他语言的经验 告诉我们有各种各样的 方法,但名称相同 偶尔会有不同的签名 有用,但也可能有用 在实践中令人困惑和脆弱。 仅通过名称和要求进行匹配 类型的一致性是主要因素 简化围棋类型中的决策 系统。
其他回答
我最终使用了参数和可变参数结构的组合。这样,我就不需要改变现有的由多个服务使用的接口,而且我的服务能够根据需要传递额外的参数。golang playground中的示例代码:https://play.golang.org/p/G668FA97Nu
所以我觉得我来这个派对已经晚了,但我一直在寻找是否有比我现在做的更好的方法。这在某种程度上解决了你试图做的事情,同时也给出了一个可选参数的概念。
package main
import "fmt"
type FooOpts struct {
// optional arguments
Value string
}
func NewFoo(mandatory string) {
NewFooWithOpts(mandatory, &FooOpts{})
}
func NewFooWithOpts(mandatory string, opts *FooOpts) {
if (&opts) != nil {
fmt.Println("Hello " + opts.Value)
} else {
fmt.Println("Hello")
}
}
func main() {
NewFoo("make it work please")
NewFooWithOpts("Make it work please", &FooOpts{Value: " World"})
}
更新1:
添加了一个功能示例,以显示功能与示例的对比
对于任意的、数量可能很大的可选参数,一个很好的习惯用法是使用Functional选项。
对于你的Foobar类型,首先只写一个构造函数:
func NewFoobar(options ...func(*Foobar) error) (*Foobar, error){
fb := &Foobar{}
// ... (write initializations with default values)...
for _, op := range options{
err := op(fb)
if err != nil {
return nil, err
}
}
return fb, nil
}
其中每个选项都是一个使Foobar发生突变的函数。然后为用户提供使用或创建标准选项的方便方法,例如:
func OptionReadonlyFlag(fb *Foobar) error {
fb.mutable = false
return nil
}
func OptionTemperature(t Celsius) func(*Foobar) error {
return func(fb *Foobar) error {
fb.temperature = t
return nil
}
}
操场上
为简洁起见,你可以给选项的类型命名(Playground):
type OptionFoobar func(*Foobar) error
如果需要强制参数,将它们作为构造函数的第一个参数添加到可变参数选项之前。
Functional options成语的主要好处是:
你的API可以随着时间的推移而增长,而不会破坏现有的代码,因为当需要新的选项时,构造函数签名保持不变。 它使默认用例变得最简单:根本没有参数! 它对复杂值的初始化提供了很好的控制。
这个技巧是由Rob Pike创造的,也由Dave Cheney演示过。
你可以使用指针,如果你不想使用它们,让它们为nil:
func getPosts(limit *int) {
if optParam != nil {
// fetch posts with limit
} else {
// fetch all posts
}
}
func main() {
// get Posts, limit by 2
limit := 2
getPosts(&limit)
// get all posts
getPosts(nil)
}
Go语言不支持方法重载,但你可以像可选参数一样使用可变参数,也可以使用interface{}作为参数,但这不是一个好的选择。