Go has no @decorator syntax. The same idea is a function that accepts a function and returns a function, or middleware wrapping handlers.
func timed(fn func()) func() {
return func() {
start := time.Now()
fn()
_ = time.Since(start)
}
}
func withLogging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println(r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
When wrapping, forward context, errors, and return values explicitly; there is no generic *args for arbitrary signatures without generics or code generation.
type Server struct{ addr string; timeout time.Duration }
type Option func(*Server)
func WithTimeout(d time.Duration) Option {
return func(s *Server) { s.timeout = d }
}
func NewServer(addr string, opts ...Option) *Server {
s := &Server{addr: addr, timeout: 30 * time.Second}
for _, o := range opts {
o(s)
}
return s
}
This is a common “configuration decorator” idiom without inheritance.