function - 为什么要在 Go 中的函数上实现接口(interface)?

标签 function go types interface functional-programming

<分区>

我在读到,在 Go 中,函数可以实现接口(interface)(like in this examplethis example)。

但是让函数实现接口(interface)有什么值(value)呢?

例如,为什么要花时间定义接口(interface)、函数的新类型和方法,如下所示:

type Handler interface {
    ServeHTTP(*Conn, *Request)
}

type HandlerFunc func(*Conn, *Request)

func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
    f(c, req)
}

当您可以像这样创建一个函数时:

func ServeHTTP(f func(*Conn, *Request), c *Conn, req *Request) {
    f(c, req)
}

提前致谢!

最佳答案

单个函数(在您的示例中,func ServeHTTP,不满足任何接口(interface)。

因此,将方法附加到函数类型的原因是满足接口(interface)

这有什么值(value)?让任何其他类型实现接口(interface)具有相同的值(value)。让我们看看 http.Handler 接口(interface),因为您已经提出了它。

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

例如,您可以使用结构来实现此接口(interface):

type myHanlder struct {
   /* some fields */
}

func (s *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    /* do things */
}

你也可以用一些更简单的类型来满足它。比如说,一个字符串:

type myStringHandler string

func (h myStringHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    _, _ = fmt.Fprintf(w, "The string is: %s", h)
}

但是如果你想直接实现函数,比如:

func myHandler(w http.ResponseWriter, r *http.Request) {
    /* do things */
}

这不满足接口(interface)。所以我们需要创建一个匹配函数签名的类型,并提供接口(interface)方法。这就是 http.HandlerFunc 所做的:

type HandlerFunc func(ResponseWriter, *Request)

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

如果问题是:为什么标准库的作者决定让 ServerHTTP 成为一个接口(interface),而不是一个函数类型,没有搜索旧邮件列表文件的线索,只有猜测是可能的,这在这里确实是题外话,但这里有一个小插曲:

  • 接口(interface)更易于使用,因为它们可以轻松扩展/嵌入。也就是说,我可以实现一个同时满足 http.Handler 接口(interface)和其他一些接口(interface)的结构。如果 http.Handler 不是一个接口(interface),这会更麻烦(尽管并非完全不可能)。
  • 这是地道的。使用“鸭子打字”界面恰好符合 Go 的做事方式。也许这有点重言式,因为它适合 Go 的原因是因为它是以这种方式完成的。
  • 如果您有一个复杂的处理程序,它可能会跟踪自己的状态,那么使用结构是自然的解决方案,并且将其作为接口(interface)公开比闭包更自然(如果将其实现为函数,则需要闭包)类型)。

作为一个思想实验,想象一下如果 io.Reader接口(interface),而不是函数类型:

type Reader func(p []byte) (n int, err error)

我认为很容易看出到处都会发生疯狂。

关于function - 为什么要在 Go 中的函数上实现接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68417772/

相关文章:

python - 在python中通过网络发送函数指针

python - Numpy 无法正确排列数组

json - this.input.get() 不起作用 beego

go - 为什么名为 "types.go"的文件在 goland 中会被忽略?

javascript - 两个对象调用同一个函数

function - 重复应用函数特定次数

go - 为什么在声明此函数时将其分为三个部分?

java - 从类型获取自动框类

java - 发现不兼容的类型 : void, 出了什么问题?

haskell - Data.Typeable.cast 到现有类型