dsv17139 2017-03-15 08:41
浏览 109
已采纳

将函数包装为函数类型有什么意义?

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?

  • 写回答

1条回答 默认 最新

  • douzhan1963 2017-03-15 08:55
    关注

    Two main reasons:

    1. 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)) { ... }
      
    2. 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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 STM32 INMP441无法读取数据
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境