亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么要在 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 關注
  • 88 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號