Sco*_*s S 2 c++ idioms go function-parameter
我想知道 Go 中的最佳实践相当于使用默认参数绑定的 C++ 函数,这对于用户来说可能是最容易看到函数参数的(在 linter 帮助下)。
您认为最 GO 风格、最简单的测试功能使用方式是什么?
C++ 中的示例函数:
void test(int x, int y=0, color=Color());
Run Code Online (Sandbox Code Playgroud)
Go 中的等价
1. 多重签名:
func test(x int)
func testWithY(x int, y int)
func testWithColor(x int, color Color)
func testWithYColor(x int, y int, color Color)
Run Code Online (Sandbox Code Playgroud)
亲:
缺点:
2. 带结构体参数:
type testOptions struct {
X int
Y int
color Color
}
func test(opt *testOptions)
// user
test(&testOptions{x: 5})
Run Code Online (Sandbox Code Playgroud)
亲:
缺点:
在模块github.com/cresty/defaults的帮助下,有一种方法可以设置默认值(但需要在运行时调用 Reflect 的成本)。
type testOptions struct {
X int
Y int `default:"10"`
color Color `default:"{}"`
}
func test(opt *testOptions) *hg.Node {
if err := defaults.Set(opt); err != nil {
panic(err)
}
}
Run Code Online (Sandbox Code Playgroud)
亲:
缺点:
...PS:我看到了可变参数or/with的使用interface{},但我发现很难知道要使用哪些参数(或者也许有一种方法可以向 linter 指示参数列表)。
无论哪种方式都可以正常工作,但在 Go 中,功能选项模式可能更适合实现此类功能。
它基于接受可变数量的WithXXX类型的函数参数的思想,这些函数参数扩展或修改调用的行为。
type Test struct {
X int
Y int
color Color
}
type TestOption func(*Test)
func test(x int, opts ...TestOption) {
p := &Test{
X: x,
Y: 12,
Color: defaultColor,
}
for _, opt := range opts {
opt(p)
}
p.runTest()
}
func main() {
test(12)
test(12, WithY(34))
test(12, WithY(34), WithColor(Color{1, 2, 3}))
}
func WithY(y int) TestOption {
return func(p *Test) {
p.Y = y
}
}
func WithColor(c Color) TestOption {
return func(p *Test) {
p.color = c
}
}
Run Code Online (Sandbox Code Playgroud)