In Go, it is possible for functions to implement interfaces. This is neat feature allows you to easily create implementations to satisfy “one-function interfaces” without creating a struct. An example for this is HandlerFunc
from the net/http
package in go. If you look at the source code for Handler
, you’ll see that it is an interface that requires a single function:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
Now, scroll a bit down, you’ll see how HandlerFunc
is defined:
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
What this effectively does, is allow the programmer to pass a HandlerFunc
into any function that accepts a Handler
.
So, you can do:
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)
}
(But don’t do this, use http.HandleFunc
instead, which would be much cleaner in this case.)
What’s more interesting is that any type in go can implement interfaces. This example has a Counter
, which is an unsigned integer, satisfy the Handler
interface:
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)
}