-1

This has confused me for the last month of learning Go:

func Auth(next http.HandlerFunc) http.HandlerFunc {

    return func(w http.ResponseWriter, r *http.Request) {  // hmmmm

        // ...
        next.ServeHTTP(w, r)
    }
}

here we can see that the Auth func returns type http.HandlerFunc. That type is just a func. So when you call next.ServeHTTP, when/where is that method defined?

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • 5
    https://golang.org/pkg/net/http/#HandlerFunc.ServeHTTP – JimB Dec 20 '18 at 01:51
  • You could also answer this question with a debugger: just put a breakpoint on that call and step into. – zerkms Dec 20 '18 at 01:52
  • 1
    `func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request)` – novalagung Dec 20 '18 at 02:00
  • I updated the OP, look at line `hmmmm`, so can you guys give a deeper answer? Maybe the core lib adds the method to the bare func somehow? How? – Alexander Mills Dec 20 '18 at 02:03
  • It's not that I care much, but seriously, why are you against using a debugger? You could have answered your question 15 minutes ago already. – zerkms Dec 20 '18 at 02:10
  • 2
    `Maybe the core lib adds the method to the bare func somehow`, you can add methods to any type. Clicking the method in the docs shows you the source, which is quite simple: https://golang.org/src/net/http/server.go?s=59784:59844#L1953 – JimB Dec 20 '18 at 02:44
  • This question is not exactly practical, but it's not a dumb question. Nobody seems to know the answer, yes looking the through the docs and debugging might get you the answer. If somebody wants points and upvotes, please just add an answer explaining how it works. This is core functionality and also might help people learn how Go works as well if "you can add methods to any type/receiver" at runtime etc. – Alexander Mills Dec 20 '18 at 02:47
  • 2
    Everybody knows the answer. It is just a method of HandlerFunc. No magic here. And no, runtime is not involved here. – Volker Dec 20 '18 at 04:41
  • @Volker explain: when the anonymous http.HandlerFunc is returned from the above Auth func, when is it given the method in question? – Alexander Mills Dec 20 '18 at 05:22
  • related? https://stackoverflow.com/questions/53862864/panic-last-argument-needs-to-be-of-type-http-handlerfunc/53862951 – Alexander Mills Dec 20 '18 at 05:39
  • 3
    The named type net/http.HandlerFunc _has_ the ServeHTTP method. It is not "given". The set of methods of a type is determined by the source code during compilation. There is no real difference between a function type and a "struct type". There is nothing to explain here. The fact that the instance of this type is function closure is of no importance here. – Volker Dec 20 '18 at 08:47
  • See also, https://stackoverflow.com/questions/49668070/how-does-servehttp-work, https://stackoverflow.com/questions/21957455/difference-between-http-handle-and-http-handlefunc, https://stackoverflow.com/questions/1774225/function-implementing-interface, https://stackoverflow.com/questions/53577614/where-does-the-servehttp-utility-come-from-on-supposedly-naked-func, etc. – JimB Dec 20 '18 at 14:44

1 Answers1

5

https://golang.org/src/net/http/server.go?s=59707:59754#L1950

// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)

// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}

Literally any function with the signature func(ResponseWriter, *Request) can be cast to a HandlerFunc, which gives it the method ServeHTTP - which then simply calls the function.

dave
  • 62,300
  • 5
  • 72
  • 93
  • can you show an example of casting a bare function to that HandlerFunc type? https://stackoverflow.com/questions/53862864/panic-last-argument-needs-to-be-of-type-http-handlerfunc/53862951 – Alexander Mills Dec 20 '18 at 05:40
  • 1
    @AlexanderMills: it's type "conversion", and the answer in that that link is an example. – JimB Dec 20 '18 at 14:45