【译】Go语言中方法实现接口
原文地址: https://karthikkaranth.me/blog/functions-implementing-interfaces-in-go
在 Go
语言中,可以用方法实现接口。这很灵巧,你不用创建一个结构体,就可以轻松的创建一个接口的实现,这个实现可以称为"一个方法-接口"(one-function interfaces
)。
net/http
包下面的 HandleFunc
方法就是一个例子,如果你看过 Handler
的源代码,你可以看到,这是一个只包含单函数的接口:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
现在,向下滑动一点,你将看到HandlerFunc
的定义:
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
这很高效,对于开发者来说,可以在接收Handler
(interface
)为参数的任意函数中传递HandlerFunc
函数作为入参。
所以,可以这样写:
func PongHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("pong"))
}
func main() {
handler := http.HandlerFunc(PongHandler)
http.Handle("/ping", handler)
http.ListenAndServe(":8080", nil)
}
(但是尽量不要这么做,在这个例子中用http.HandleFunc
1替代,这样会更清晰)
更有趣的是,在Go
语言中任意类型都可以实现接口。下面就是一个无符号整型的计数器例子,它实现了Handler
接口:
type Counter uint64
func (i *Counter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
*i++
response := fmt.Sprintf("%v", *i)
w.Write([]byte(response))
}
func main() {
var c Counter
http.Handle("/count", &c)
http.ListenAndServe(":8080", nil)
}
-
作者在这个例子中两次提到
http.Handle.Func
, 容易造成混淆,这里解释一下。 第一次handler := http.HandlerFunc(PongHandler)
中是指类型强制转化,第二次是http
包的HandleFunc
函数。 ↩