1 回答

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.Handler
http.Handler
這是慣用語。使用“鴨子打字”的界面正好符合Go的做事方式。也許這有點重復,因為它適合Go的原因是因為它是以這種方式完成的。
如果你有一個復雜的處理程序,它可能跟蹤它自己的狀態,使用結構是自然的解決方案,并且將其公開為接口比閉包更自然(如果這是作為函數類型實現的,則需要閉包)。
作為一個思想實驗,想象一下如果io。讀取器
接口,其中函數類型:
type Reader func(p []byte) (n int, err error)
我認為很容易看出瘋狂會接踵而至。
- 1 回答
- 0 關注
- 88 瀏覽
添加回答
舉報