Generic Functional Options for Go.
$ go get -u github.com/RussellLuo/gopt
package main
import (
"fmt"
"github.com/RussellLuo/gopt"
)
type Server struct {
host string
port int
}
func New(options ...gopt.Option[*Server]) *Server {
return gopt.Apply(new(Server), options...)
}
// ServerOption holds all option factories for Server.
type ServerOption struct{}
func (ServerOption) Host(host string) gopt.Option[*Server] {
return func(s *Server) { s.host = host }
}
func (ServerOption) Port(port int) gopt.Option[*Server] {
return func(s *Server) { s.port = port }
}
func main() {
server := New(
ServerOption{}.Host("localhost"),
ServerOption{}.Port(8080),
)
fmt.Printf("server: %+v\n", server)
// Output:
// server: &{host:localhost port:8080}
}
-
Why might I want to use this tiny library?
Traditional Functional Options will define many exported functions, which is likely to cause naming conflicts.
Reference articles:
- Golang Functional Options Pattern
- Go Patterns' Functional Options
Reference projects:
- gRPC-Go's DialOption
- Go kit's ServerOption
-
Why is
ServerOption{}
used in the example?ServerOption
is a named alias of the empty struct, whose instances are fungible and consume no space.
Unsafe gopt is an early implementation, which is deprecated and for reference only.