yet another style for optional args in go
This is just a simple little twist on the recommendation from Evan Jones to use structs rather than functional options.
The basic problem is that you have a function that potentially has many parameters. This most often happens with NewThing
funcs where you’re creating a struct with private fields.
To steal Evan’s example:
func NewFoo(options ...FooOption) *Foo {
// ... implementation
}
func CallNewFoo() *Foo {
return NewFoo(WithBoolOption(), WithIntOption(42))
}
And his advice on what to do instead:
func NewFooStruct(config FooConfig) *Foo {
// ... implementation
}
func CallNewFooStruct() *Foo {
return NewFooStruct(FooConfig{BoolOption: true, IntOption: 42})
}
I propose that the “config” struct containing the optional parameters be labeled NewFoo
, and that it have a single method .Create()
.
type NewFoo struct {
BoolOption bool,
IntOption int,
// ...
}func (nf NewFoo) Create() *Foo {
// make a new *Foo and return it
}
This yields a call style like this:
myFoo := NewFoo{ BoolOption: true, IntOption: 42 }.Create()
This, to my eyes is easier to read, and it is very clear what’s going on. (More so than NewFooStruct(FooConfig{...})
at least.)
The only trick is designing the options struct such that zero-values always indicate the “default”, so that they can be omitted in the call. (This applies in the other style of config-by-struct, too.)
Obviously, this same style can be used for non-builder funcs. We tend to thing of structs as “objects” which need to be created, and tend to stick around, but clearly that’s not a real requirement. It’s perfectly fine to create a struct value for a single method invocation.
E.g., something like this:
result := ComputeComplex{ OptA: 12, OptD: 3, OptJ: "ack" }.Exec()
So, yet another option for how to “simplify” your code. 😃
[It should be noted that Rob Pike did mention “option structs” in the original blog post that kicked this all off. My reading of that post is that using config/option structs is as not “interesting” as using “self-referential functions”, and Rob never actually tried to promote that style as The Right Way, he only says “You might like it too. Or you might not…”]