I am new to golang and I've seen occasionally some code that wraps a function inside a function type. In http package we have this as well:
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
I'm curious to know the reason behind. If we want to have a type that exposes a method why don't we create a struct type and add the method to it?
Two main reasons:
Convenience when receiving functions as arguments:
type LongFuncSig func(a int, b *int, c string, d *SomeWeirdThing, f map[string]*Foo, g ...interface{}) (*Result, error)
func DoSomething(fn LongFuncSig) { ... }
func DoSomethingElse(fn LongFuncSig) { ... }
func DoYetAnotherThing(fn LongFuncSig) { ... }
Is much more readable, and less error-prone than:
func DoSomething(fn func(a int, b *int, c string, d *SomeWeirdThing, f map[string]*Foo, g ...interface{}) (*Result, error)) { ... }
func DoSomethingElse(fn func(a int, b *int, c string, d *SomeWeirdThing, f map[string]*Foo, g ...interface{}) (*Result, error)) { ... }
func DoYetAnotherThing(fn func(a int, b *int, c string, d *SomeWeirdThing, f map[string]*Foo, g ...interface{}) (*Result, error)) { ... }
When you want to attach methods to the type.
In your example, http.HandlerFunc
has an attached method, ServeHTTP
. This causes the function to satisfy the http.Handler
interface. It's only possible to attach methods to named types.
And to answer your related question:
If we want to have a type that exposes a method why don't we create a struct type and add the method to it?
Because there's no reason to do do that. The standard library could have chosen to take your suggestion with:
type HandlerFunc struct {
Func func(ResponseWriter, *Request)
}
But that's far more verbose, and harder to use and read. To use that, you'd then have to call:
http.HandlerFunc{Func: fn}
instead of the much simpler:
http.HandlerFunc(fn)
So there's no reason to add unnecessary complexity.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With