Reputation: 18771
package main
import (
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){
w.Write([]byte("hello world"))
})
http.ListenAndServe(":8000", nil)
}
If I remove the *
in http.Request
:
github.com/creating_web_app_go/main.go:8: cannot use func literal (type func(http.ResponseWriter, http.Request)) as type func(http.ResponseWriter, *http.Request) in argument to http.HandleFunc
I'm very new to both Go and pointers.
So the Question is,
why must http.Request
be a pointer rather than a func literal
? Can anyone explain this in the simplest way possible, with perhaps a reference to source code?
Upvotes: 4
Views: 2413
Reputation: 48076
Because that's how functions work. They have arguments and when you invoke them you must provide the required arguments. The types have to be the same as well.
I think you're really asking; Why is it designed that way?
Because you're providing a delegate for http.HandleFunc
to invoke when a request is made to the root "/"
. In most cases when a RESTful API is handling a request it needs to know information in the request, stuff like the headers, query parameters and/or post body... If you don't want to make use of that information you don't have to, it's not much overhead to pass a reference into a function. But for just about every real use case, the data is needed so it's included, so it is made an argument in the delegate you provide. From the persepctive of their implemenation, they need to know what the method signature is that you provide so they can invoke it.
So to clarify, the thing you're looking at is the required signature for the func
you provide as the second argument to http.HandleFunc
. The first argument is the path. It invokes that method when an http request is made to the provided path. That code is going to call that argument call it handler
and it needs a consistent definition so that it can do handler(resp, req)
and not have to do reflection or a switch or some other control flow just to call into your code.
Upvotes: 3
Reputation: 299265
Because it's a large struct. Copying it would be expensive. So it's a pointer to a struct, which is common in Go when structs are large. Also it has some state, so it would likely be confusing if it were copied. It would make no sense to be a func literal; I don't understand why that would be an option.
Upvotes: 16