Functional Options in Go @ [Billy Lam] | Monday, Feb 22, 2021 | 2 minutes read

A nice way to set options in Go

Functional Option

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

type Foo struct {
    Code      int
    Verbosity int
    Timeout   time.Duration // In nanoseconds
}

type option func(*Foo)

func main() {
    fmt.Println("Demo for option chain")
    foo := New(5)

    fmt.Println("Before")
    fmt.Println(PrettyPrint(foo))

    fmt.Println("After")
    foo.Option(Verbosity(-1))     // Set verbosity
    foo.Option(SetTimeout("10s")) // Set timeout to 10 sec

    fmt.Println(PrettyPrint(foo))
}

func New(code int) Foo {
    return Foo{
	Code: code,
    }
}

// Option sets the options specified.
func (f *Foo) Option(opts ...option) {
    for _, opt := range opts {
	opt(f)
    }
}

// Verbosity sets Foo's verbosity level to v.
func Verbosity(v int) option {
    return func(f *Foo) {
	f.Verbosity = v
    }
}

// SetTimeout sets timeout using ParseDuration
// input is like 5s, 1m, etc
func SetTimeout(t string) option {
    timeout, _ := time.ParseDuration(t)
    return func(f *Foo) {
	f.Timeout = timeout
    }
}

// PrettyPrint to print struct in a readable way
func PrettyPrint(i interface{}) string {
    s, _ := json.MarshalIndent(i, "", "\t")
    return string(s)
}

Results

// Demo for option chain

// Before
// {
//         "Code": 5,
//         "Verbosity": 0,
//         "Timeout": 0
// }
// After
// {
//         "Code": 5,
//         "Verbosity": -1,
//         "Timeout": 10000000000
// }

You can find the complete working example in - Here

Reference: Self-referential functions and the design of options

© 2021 Fullstack Data Science Blog

avatar

Another Data Science BlogThe dark side of Data Science

Me