在函数类型中包装函数有什么意义?

Jav*_*iri 7 go

我是Golang的新手,我偶尔会看到一些代码在函数类型中包含一个函数.在http包中我们也有这个:

type HandlerFunc func(ResponseWriter, *Request)

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}
Run Code Online (Sandbox Code Playgroud)

我很想知道背后的原因.如果我们想要一个暴露方法的类型,为什么我们不创建一个结构类型并将方法添加到它?

Fli*_*mzy 5

两个主要原因:

  1. 接收函数作为参数时的便利性:

    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)
  2. 如果要将方法附加到类型.

    在您的示例中,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)

    所以没有理由增加不必要的复杂性.