我是Golang的新手,我偶尔会看到一些代码在函数类型中包含一个函数.在http包中我们也有这个:
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
Run Code Online (Sandbox Code Playgroud)
我很想知道背后的原因.如果我们想要一个暴露方法的类型,为什么我们不创建一个结构类型并将方法添加到它?
两个主要原因:
接收函数作为参数时的便利性:
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) { ... }
Run Code Online (Sandbox Code Playgroud)
比以下内容更具可读性,更不容易出错:
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)) { ... }
Run Code Online (Sandbox Code Playgroud)如果要将方法附加到类型.
在您的示例中,http.HandlerFunc有一个附加的方法,ServeHTTP.这使得函数满足http.Handler接口.只能将方法附加到命名类型.
并回答您的相关问题:
如果我们想要一个暴露方法的类型,为什么我们不创建一个结构类型并将方法添加到它?
因为没有理由这样做.标准库可以选择将您的建议与:
type HandlerFunc struct {
Func: func(ResponseWriter, *Request)
}
Run Code Online (Sandbox Code Playgroud)
但这更加冗长,更难以使用和阅读.要使用它,您必须致电:
http.HandlerFunc{Func: fn}
Run Code Online (Sandbox Code Playgroud)
而不是更简单:
http.HandlerFunc(fn)
Run Code Online (Sandbox Code Playgroud)
所以没有理由增加不必要的复杂性.