Functions implementing interfaces in go

PUBLISHED ON APR 18, 2018

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)
}