As the documentation said
Do not store Contexts inside a struct type; instead, pass a Context explicitly to each function that needs it. The Context should be the first parameter, typically named ctx
but I found, in the typical http request handle function, a http.Request object has .Context() method can retrieve the context which http request associate with.
So why recommend to use context as the first parameter in these functions? Is that reasonable in this situation?
I know that is not an absolute rule. But I want to know why the HandlerFunc is func(ResponseWriter, *Request) instead of func(context.Context, ResponseWriter, *Request).
Apparently HandlerFunc breaks this recommendation.
As described in the documentation you quoted above,
ctxshould be a (very) common argument for many functions. This is similar to the way many functions return anerror. The best place for a common argument/return value is either as the first, or last in a list. (Arguably, Go could have chosen to makeerroralways be the first return value--I won't discuss that here).Since variadic variables may only be the last in the list of function arguments, this leaves the only option for a common argument to be the first one.
I expect this is why
ctxis always first.This pattern is often seen with other variables in Go (and other languages) as well. Any time a common variable is used by a set of related functions, that common variable often comes first in the argument list (or possibly second, after
ctx).Contrary to the advice you quoted, there are libraries that store
ctxin a struct, rather than passing it around as the first argument. These are usually (always?) libraries which had to be retro-fitted to usectx, long after the library contract was set in stone (by the Go 1.x compatibility guarantee).Generally, you should follow the advice to pass
ctxas the first argument, for any new work.