大猩猩的背景包
存储在请求生命周期内共享的值.
官方context包裹
跨API边界和进程之间传递截止日期,取消信号和其他请求范围的值.
因此,从一开始,官方包装显然做得更多.但在进入细节之前,有一些历史:
Gorilla的上下文包早于官方Go上下文包.它是为了解决响应HTTP请求时的基本问题而创建的:不同的中间件和处理程序需要能够共享请求范围的状态.诸如经过身份验证的用户名和用户ID之类的内容,以及在将数据发送到要解析的模板之前从数据库中检索的信息的结果等.
Gorilla的上下文包通过一个相当丑陋的黑客来实现:它创建了一个以HTTP请求指针为关键字的地图.为了使这种并发安全,它将所有对此映射的访问包装在互斥锁中,这使得访问速度变慢(尽管实际上,它可能只对非常繁忙的网站有用).
如上所述,Go上下文包稍后出现,并考虑到不同的需求.Go上下文包主要用于解决在不再需要操作后取消操作的问题.
在此之前,如果您正在提供HTTP请求,并且用户关闭了他们的Web浏览器或点击"停止"按钮,或者他们的WiFi连接丢失,您将无从得知.您的服务器很乐意继续使用,从数据库中获取值,渲染模板等,只是为了将结果发送回... nobody.
或许你的程序需要从一堆远程API中获取数据,但你只愿意等待10秒.10秒后,您要取消待处理的请求.
使用Go上下文包,这些东西是可能的 - 而且很简单.通过提供可取消的上下文,http库现在可以告诉您的HTTP服务器客户端已取消HTTP请求.或者,您可以为后一个方案设置超时的上下文.
所以你可以看到,这两个软件包旨在解决完全不同的问题.
但是,官方的Go上下文包还有一个额外的功能.该WithValue方法可以让你沿着上下文任意数据传递.这确实与Gorilla的上下文包有相同的目的,但有点像后来的想法.
这些天最好的做法是使用官方上下文包.但这应该主要是为了取消目的.作为次要好处,您还可以使用它来传递值 - 您将在Gorilla的上下文中传递的相同类型的值.
但是,如果你只是用它来传递价值观,你就会失去大约90%的收益.