Last active
March 10, 2019 05:07
-
-
Save enjoylife/35bf50b3071811d259b59351332b3dfc to your computer and use it in GitHub Desktop.
Practical example using functional options for creating extendable functions in Go(golang).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"fmt" | |
) | |
// An ServerOption configures our Server | |
type ServerOption interface { | |
apply(s *Server) // 😈 an option is now ours and ours alone to implement | |
} | |
// optionFunc wraps a func so it satisfies the ServerOption interface. | |
type optionFunc func(*Server) | |
// apply satisfies the interface and | |
// invokes the optionFunc | |
func (f optionFunc) apply(s *Server) { | |
f(s) | |
} | |
// Use OptionHost to set the host the server will use. | |
func OptionHost(host string) ServerOption { | |
return optionFunc(func(s *Server) { | |
s.host = host | |
}) | |
} | |
// Use OptionPort to set the port the server will use. | |
func OptionPort(port int) ServerOption { | |
return optionFunc(func(s *Server) { | |
s.port = port | |
}) | |
} | |
// This is the type whose options you're enabling users to set. | |
type Server struct { | |
host string | |
port int | |
} | |
// This is your creator function that accepts a list of option functions. | |
func NewServer(opts ...ServerOption) *Server { | |
s := &Server{} | |
// call option functions on instance to set options on it | |
for _, opt := range opts { | |
opt.apply(s) | |
} | |
return s | |
} | |
func (s *Server) Addr() string { | |
return fmt.Sprintf("%s:%d", s.host, s.port) | |
} | |
func main() { | |
var host = flag.String("host", "127.0.0.1", "host") | |
var port = flag.Int("port", 3000, "port") | |
flag.Parse() | |
// This is how your user sets the options. | |
s := NewServer( | |
OptionHost(*host), | |
OptionPort(*port), | |
) | |
fmt.Printf("Server available at %s", s.Addr()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment