yet another style for optional args in go

Patrick Kelly
2 min readMay 28, 2022

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…”]

--

--

Patrick Kelly

Web/database engineer/gopher. Cycling, photos, yada, yada.