可变参数函数是否适合作为可选参数的解决方案?

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

Is a variadic function an appropriate solution for optional argument?

问题

如果我有一个函数,其中最后一个参数是可选的,使用...来允许参数是可选的,这样做是否是合适的做法,还是被认为是不好的形式?

示例:

func Foo(s ...string) {
    switch len(s) {
        case 0:
            fmt.Println("You didn't pass an argument")
        case 1:
            fallthrough
        default:
            fmt.Printf("You passed %s\n", s[0])
    }
}

Foo("bar")        // "You passed bar"
Foo()             // "You didn't pass an argument"
Foo("bar", "baz") // "You passed bar"

在这个示例中,我不关心是否传递了太多的参数,但在需要时可以在default:情况下处理它。

英文:

If I have a function where the last argument is optional, is it an appropriate practice to use ... to allow the argument to be optional, or is it considered bad form?

Example:

func Foo(s ...string) {
    switch len(s) {
        case 0:
            fmt.Println("You didn't pass an argument")
        case 1:
            fallthrough
        default:
            fmt.Printf("You passed %s\n", s[0])
    }
}

Foo("bar")        // "You passed bar"
Foo()             // "You didn't pass an argument"
Foo("bar", "baz") // "You passed bar"

In this example, I don't care if too many arguments were passed, but I could handle that in the default: case when needed.

答案1

得分: 12

如果你真的需要可选参数(正如你从Go标准库中看到的那样,这是很少见的),惯用的方式是定义一个结构体,其中包含每个可选参数的字段,然后调用者可以传递一个结构体字面量,填充他们想要的字段。

更常见的做法是在只有一个或两个“可选”参数时提供替代的函数或方法,这在大多数情况下都是如此。

在像Python这样的语言中,可选参数通常意味着API会不断增长,直到函数和方法的参数超过任何人能记住的数量,并且很难弄清楚各种参数组合的相互作用(它们甚至经过的测试更少)。

强制你为各种参数组合定义显式的函数和方法需要更多的API设计思考,但从长远来看,它使API更易用和可维护。

英文:

If you really need optional arguments (and as you can see from the Go stdlib, it is rare), the idiomatic way is to define a struct with fields for each of the optional arguments, and then callers can pass a struct literal with the fields they want filled in.

More common is to provide alternative function or methods, when it is only one or two "optional" arguments, which should be most of the time.

Optional arguments in languages like Python often mean that the API grows and grows until functions and methods have more arguments than anyone can remember, and it is never clear how various combinations of arguments interact (and they are even less tested).

Forcing you to define explicit functions and methods for the various combinations of parameters requires more thought up front about your API, but makes it much more usable and maintainable in the long term.

答案2

得分: 6

我不建议这样做。滥用可变参数传递可选参数存在不同的问题。其中最重要的问题可能是最后一个arg ...T)的形式只允许一个类型。对于多个可选参数和多个类型,可以使用...interface{},但这会产生不必要的运行时(解)封箱成本,并且缺乏任何(有用的)编译时类型检查。

另一个可能的反对意见是,我认为您在标准库中找不到这样的示例/先例,标准库被一些人认为是Go编码风格指南的非正式参考。

英文:

I would not recommend this. There are different problems with (ab)using variadic parameters for passing optional arguments. Most important of them is probably that the form of the last arg ...T) allows for only one type. For more than one optional parameter with more than one type one can use ...interface{} but that incurs unnecessary run time (un)boxing costs and lacks any (usefull) compile time type checking.

Another possible argument against is that I don't think you'll find an example/precedent for this anywhere in the standard library, which is considered an informal Go coding style guide by some.

答案3

得分: 0

这完全取决于您的项目需求,如果您的项目处于这种情况下,那么没有任何不好的形式。

可选参数facility仅针对这种情况提供。

英文:

It's all depends on your projects requirements, if your project is in a situation like this, then there is not any bad form

The optional argument facility is provided only for this kind of situation.

huangapple
  • 本文由 发表于 2012年9月22日 21:20:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/12544131.html
匿名

发表评论

匿名网友

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

确定