package main import "fmt" type SetFilterFunc func(options *FilterOptions) type FilterOptions struct { Alive *bool Id *int ExternalId *string } type Filter struct { Options FilterOptions } func (f *Filter) Dump() { if f.Options.Alive != nil { fmt.Printf("Alive: %v\n", *f.Options.Alive) } if f.Options.Id != nil { fmt.Printf("Id: %v\n", *f.Options.Id) } if f.Options.ExternalId != nil { fmt.Printf("ExternalId: %v\n", *f.Options.ExternalId) } } func WithAlive(options *FilterOptions) { alive := true options.Alive = &alive } func WithId(id int) SetFilterFunc { return func(options *FilterOptions) { options.Id = &id } } func WithExternalId(externalId string) SetFilterFunc { return func(options *FilterOptions) { options.ExternalId = &externalId } } func NewFilter(opts ...SetFilterFunc) *Filter { f := Filter{Options: FilterOptions{}} for _, fn := range opts { fn(&f.Options) } return &f } func main() { var f *Filter f = NewFilter() f.Dump() fmt.Println("-------------------") f = NewFilter(WithId(123), WithAlive, WithExternalId("some-external-id")) f.Dump() }