为什么推荐使用 ctx 作为第一个参数?

Why recommand use ctx as first paramenter?

如文档所述

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

但我发现,在典型的http请求句柄函数中,一个http.Request对象有.Context()方法可以检索http请求关联的上下文。

那么为什么建议在这些函数中使用上下文作为第一个参数。在这种情况下这样做合理吗?


我知道这不是限制规则。但我不知道为什么 HandlerFuncfunc(ResponseWriter, *Request) 而不是 func(context.Context, ResponseWriter, *Request)

显然,HandlerFunc违反了建议。

如您在上面引用的文档中所述,ctx 应该是许多函数的(非常)通用参数。这类似于许多函数 return 和 error 的方式。常见 argument/return 值的最佳位置是列表中的第一个或最后一个。 (可以说,Go 可以选择让 error 总是第一个 return 值——我不会在这里讨论)。

由于 variadic 变量可能 是函数参数列表中的最后一个,这使得公共参数成为第一个参数的唯一选择。

我想这就是 ctx 总是第一个的原因。

Go(和其他语言)中的其他变量也经常看到这种模式。任何时候一组相关函数使用公共变量时,该公共变量通常在参数列表中排在第一位(或者可能在 ctx 之后排在第二位)。


与您引用的建议相反,有些库将 ctx 存储在结构中,而不是将其作为第一个参数传递。这些通常(总是?)库必须经过改造才能使用 ctx,在库合同一成不变(通过 Go 1.x 兼容性保证)很久之后。

一般来说,对于任何新作品,您都应该遵循将 ctx 作为第一个参数传递的建议。