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

时间:2017-03-15 08:41:49

标签: go

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

type HandlerFunc func(ResponseWriter, *Request)

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}

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

1 个答案:

答案 0 :(得分: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) { ... }
    

    比以下内容更具可读性,更不容易出错:

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

    在您的示例中,http.HandlerFunc有附加方法ServeHTTP。这会导致函数满足http.Handler接口。它只能将方法附加到命名类型。

    并回答你的相关问题:

      

    如果我们想要一个暴露方法的类型,为什么我们不创建一个结构类型并将方法添加到它?

    因为没有理由这样做。标准库可以选择接受您的建议:

    type HandlerFunc struct {
        Func: func(ResponseWriter, *Request)
    }
    

    但那更加冗长,更难以使用和阅读。要使用它,您必须致电:

    http.HandlerFunc{Func: fn}
    

    而不是更简单:

    http.HandlerFunc(fn)
    

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