Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Functional config in go

Quick demo of how to initialize your data structure with optional configuration parameters ... with sane defaults if left unspecified.

This functional config technique ...

  • lets you write APIs that can evolve without pain
  • provides meaningful configuration parameters
  • makes it easy to set default settings
  • makes it possible to set complex conditional values

See the posts by Rob Pike ("Self-referential functions and the design of options") and Dave Cheney ("Functional options for friendly APIs") for more details on this technique.

package main
import (
func main() {
bill, _ := person.New("Bill") // sets defaults for Job, Age, Alive
fmt.Printf("%#v\n", bill)
// {Name:"Bill", Age:0, Job:"unknown", Alive:true}
bob, _ := person.New("Bob", person.Job("programmer"),
fmt.Printf("%#v\n", bob)
// {Name:"Bob", Age:44, Job:"programmer", Alive:true}
// change bob's configuration
fmt.Printf("%#v\n", bob)
// {Name:"Bob", Age:33, Job:"masseuse", Alive:false}
package person
import "fmt"
type Person struct{
Name string
Age int
Job string
Alive bool
func (p *Person) String() string {
return fmt.Sprintf("%s, %v, %s, %v", p.Name, p.Age, p.Job, p.Alive)
type option func(*Person)
// Config sets the options specified.
func (p *Person) Config(opts ...option) {
for _, opt := range opts {
func Age(yrs int) option {
return func(p *Person) {
p.Age = yrs
func Job(job string) option {
return func(p *Person) {
p.Job = job
func Alive(status bool) option {
return func(p *Person) {
p.Alive = status
func New(name string, options ...option) (*Person, error) {
p := Person{
Name: name,
Age: 0,
Job: "unknown",
Alive: true,
for _, opt := range options {
return &p, nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment