Functional options in Go
The Go answer to optional arguments: variadic functions that mutate a config.
type Server struct {
addr string
timeout time.Duration
verbose bool
}
type Option func(*Server)
func WithTimeout(d time.Duration) Option {
return func(s *Server) { s.timeout = d }
}
func WithVerbose() Option {
return func(s *Server) { s.verbose = true }
}
func NewServer(addr string, options ...Option) *Server {
server := &Server{addr: addr, timeout: 30 * time.Second}
for _, apply := range options {
apply(server)
}
return server
}
func configured() string {
s := NewServer(":8080", WithTimeout(time.Second), WithVerbose())
return fmt.Sprintf("%s %s %t", s.addr, s.timeout, s.verbose)
}
How it works
- Each option is a function that edits the struct.
- The constructor applies the defaults, then the options.
- Adding an option later breaks no existing caller.
Keywords and builtins used here
boolforfuncrangereturnstringstructtype
The run, in numbers
- Lines
- 28
- Characters to type
- 596
- Tokens
- 155
- Three-star pace
- 110 tpm
At the three-star pace of 110 tokens a minute, this run takes about 85 seconds.
Step 1 of 2 in API shapes, step 17 of 19 in Interfaces & generics.