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

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Patrick Kelly
Patrick Kelly

Written by Patrick Kelly

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

No responses yet

Write a response