Hacker News new | ask | show | jobs
by gabesullice 856 days ago
Not the OP, but I mitigate the issue rather than use a different pattern. Like so:

type Server struct { val bool }

type Config struct { Val bool }

func NewServer(... config *Config ...) http.Handler { if config == nil { config = &Config{} } return &Server{ val: config.Val } }

It took me a long time to settle on this pattern and I admit it's tedious to copy configuration over to the server struct, but I've found that it ends up being the least verbose and maintainable long term while making sure callers can't mutate config after the fact.

I can pass nil to NewServer to say "just the usual, please", customize everything, or surgically change a single option.

It's also useful for maintaining backwards compatibility. I'm free to refactor config on my server struct and "upgrade" deprecated config arguments inside my NewServer function.