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