为了账号安全,请及时绑定邮箱和手机立即绑定

为什么要在 Go 中的函数上实现接口?

为什么要在 Go 中的函数上实现接口?

Go
慕的地6264312 2022-09-12 20:57:27
我正在阅读,在Go中,函数可以实现接口(如本例或本例所示)。但是,让函数实现接口有什么价值呢?例如,为什么要花时间定义一个接口、函数的新类型和一个方法,如下所示: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)}提前致谢!
查看完整描述

1 回答

?
梦里花落0921

TA贡献1772条经验 获得超6个赞

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


因此,将方法附加到函数类型的原因是为了满足接口。


这有什么价值?让任何其他类型实现接口时具有相同的值。让我们看一下界面,因为您提出了这一点。http.Handler


type Handler interface {

    ServeHTTP(ResponseWriter, *Request)

}

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


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 */

}

这不能满足界面。因此,我们需要创建一个与函数签名匹配的类型,并提供接口方法。这是做什么的:http.HandlerFunc


type HandlerFunc func(ResponseWriter, *Request)


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

    f(w, r)

}

如果问题是:为什么标准库的作者决定制作一个接口,而不是一个函数类型,而不搜索旧的邮件列表存档中的线索,只有推测是可能的,这在这里真的偏离了主题,但这里有一个小小的尝试:ServerHTTP

  • 接口更易于使用,因为它们可以轻松扩展/嵌入。也就是说,我可以实现一个同时满足接口和其他一些接口的结构。如果不是界面,这将更加繁琐(尽管并非严格不可能)。http.Handlerhttp.Handler

  • 这是惯用语。使用“鸭子打字”的界面正好符合Go的做事方式。也许这有点重复,因为它适合Go的原因是因为它是以这种方式完成的。

  • 如果你有一个复杂的处理程序,它可能跟踪它自己的状态,使用结构是自然的解决方案,并且将其公开为接口比闭包更自然(如果这是作为函数类型实现的,则需要闭包)。

作为一个思想实验,想象一下如果io。读取器接口,其中函数类型:

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

我认为很容易看出疯狂会接踵而至。


查看完整回答
反对 回复 2022-09-12
  • 1 回答
  • 0 关注
  • 111 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号