【问题标题】:Why recommand use ctx as first paramenter?为什么推荐使用 ctx 作为第一个参数?
【发布时间】:2022-01-03 21:45:44
【问题描述】:

如文档所述

不要将上下文存储在结构类型中;相反,将 Context 显式传递给需要它的每个函数。 Context应该是第一个参数,通常命名为ctx

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

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


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

显然,HandlerFunc 破坏了建议。

【问题讨论】:

  • 推荐的不错,坚持下去。请注意,对于 http 包,要在不破坏兼容性的情况下改装 Context hat。这里没什么可看的。
  • 这是一个约定。就像节点中的“错误第一个回调”。
  • @Volker 所以你的意思是添加.Context() 只是为了不破坏兼容性?这不是最佳做法?
  • 是的,这最佳实践。违反保证的兼容性承诺将是一种糟糕的做法。
  • req.Context() 与破坏向后兼容性无关?请求存储一个上下文,以便您可以随时检索它(鉴于http.Request 在这种意义上是一个值对象)

标签: http go backend go-context


【解决方案1】:
Go Language推荐的答案

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

由于variadic 变量可能是函数参数列表中的最后一个,因此公共参数的唯一选择是第一个。

我想这就是为什么ctx 总是第一的原因。

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


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

通常,对于任何新工作,您都应该按照建议将ctx 作为第一个参数传递。

【讨论】:

  • 谢谢,作为一个新人http包的区别真的让我很困惑
猜你喜欢
  • 2012-06-26
  • 2013-04-25
  • 1970-01-01
  • 2016-02-23
  • 2017-11-04
  • 2011-10-22
  • 2011-04-11
  • 2021-10-12
相关资源
最近更新 更多