如何干净地向函数添加一个参数

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

How to cleanly add an argument to a function

问题

我有一个被调用了很多次的函数。现在我想在这个函数中添加一个额外的参数,而不必修改所有的调用点(即在那里插入默认值并添加一堆噪音),同时保持类型安全。我之前使用的所有语言都支持默认参数或重载,所以我对如何实现这个功能感到很困惑。

英文:

I have a function that's called quite a few times. How do I now add an additional parameter to that function without having to modify all the call-sites (essentially intruding the default value there and adding a bunch of noise) as well as keeping type safety?

All the languages I have previously used either support default arguments or overloading, so I am quite lost as to how I would do that.

答案1

得分: 9

Go语言没有默认参数,也没有函数重载。我认为,在不改变其余代码的情况下,你可以做以下操作:

1)将函数Func()重命名为FuncWithNewArg()
2)在FuncWithNewArg()中添加一个新的参数
3)创建一个名为Func()的新函数,其签名与原始函数相同。Func()将调用FuncWithNewArg(),传递所有的参数以及新参数的默认值。

英文:

Go doesn't have default arguments, neither it has function overloading. I think, the best you can do without changing the rest of the code is:

  1. Rename the function Func() to FuncWithNewArg()
  2. Add a new argument to FuncWithNewArg()
  3. Create a new function named Func() with the original signature. Func() will call FuncWithNewArg() passing all its argument plus the default value for the new one.

答案2

得分: 2

在Go语言中,向函数添加可选参数的唯一方法是使用可变参数函数(variadic function)。只要你的函数没有任何可变参数,你就可以添加一个可变参数而无需更新所有现有的调用者。但是,这会改变函数的签名,因此如果有任何依赖于该签名的东西(例如将函数分配给变量),这些东西可能会出错。

举个例子,假设你的函数是这样的:

func Foo(count int) error {
    // do stuff
}

你可以在末尾添加一个可选的可变参数:

func Foo(count int, optional ...string) error {
    // do stuff
}

然后,你可以将optional变量作为指定类型的切片(在这种情况下是[]string)来访问。

现在,Foo()可以被调用为Foo(3)Foo(3, "bar")

实际上,它可以被调用任意数量的参数,只要它们与可变参数的类型匹配。例如,Foo(3, "bar", "baz", "qux")也是有效的。

一个函数只能接受一个可变参数,并且它必须是最后一个参数。这意味着你不能混合和匹配类型。例如,下面的代码是无效的:

func Foo(count int, optional ...string, alsoOptional ...float64) error 

如果你需要比这更灵活的东西,最好的方法是添加一个新的函数,就像@bereal的答案中建议的那样:

func Foo(count int) error { ... }

func FooWithOther(count int, other string) error { ... }
func FooWithMany(count int, other string, more bool) error { ... }
英文:

The only way to add an optional argument to a function in Go is with a variadic function. As long as your function doesn't already have any variadic variables, you can add one without requiring all the existing callers to update. However, this does change the function signature, so if you have anything depending on that signature (i.e. assigning the function to a variable), such things may break.

To illustrate, suppose your function is:

func Foo(count int) error {
    // do stuff
}

You could add an optional variadic variable at the end:

func Foo(count int, optional ...string) error {
    // do stuff
}

You then access the optional variable as as a slice of the designated type ([]string in this case).

Now Foo() can be called as either Foo(3) or Foo(3, "bar").

Actually, it can be called with any number of arguments, so long as they match the type of the variadic variable. I.e. Foo(3, "bar", "baz", "qux") is also valid.

A function can take only a single variadic variable, and it must be the last one. This means you can't mix and match types. For example, this is invalid:

func Foo(count int, optional ...string, alsoOptional ...float64) error 

If you need something more flexible than this, your best bet is to add a new function, as suggested in @bereal's answer:

func Foo(count int) error { ... }

func FooWithOther(count int, other string) error { ... }
func FooWithMany(count, int, other string, more bool) error { ... }

huangapple
  • 本文由 发表于 2021年8月19日 20:07:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/68847585.html
匿名

发表评论

匿名网友

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

确定