Golang Go语言中有没有什么开源库,给 context 预留 Value 的坑?

发布于 1周前 作者 htzhanglong 来自 Go语言

比如下面的程序

func F1(ctx context.Context) {
	// A
}

func F2(ctx context.Context) { // C

F1(ctx)

// B

}

A 处,可以取得一些变量。

现实是 B 处需要 A 获得的变量。 一个办法,修改函数 F1 ,让 F1 返回 B 需要的数据。 或者,C 处给 ctx 塞一个 value 坑,F1 把数据存到 value 坑上,B 再取到 value 。但不知道有没有什么开源程序,已经实现了这个?


Golang Go语言中有没有什么开源库,给 context 预留 Value 的坑?

更多关于Golang Go语言中有没有什么开源库,给 context 预留 Value 的坑?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

首先,这是 feature ,正常的业务代码不建议这样子写。
你要的其实是类似 Java 的 ThreadLocal ,一般传来传递一个 request 的上下文,tracing 之类的。
要实现也很简单,在入口或者中间件,给 context 放一个 map 就可以了,在 F1 函数将需要的值写入这个 map 。

更多关于Golang Go语言中有没有什么开源库,给 context 预留 Value 的坑?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


context 里面塞业务逻辑太骚了吧。直接返回值我觉得更好。

Go context 包本身支持 context.WithValue 和 ctx.Value 这个设置和获取的方法;应该常见的 gin 、echo 的库在请求上下文也是支持自定义设置值的,可以参考

最后不这么用,context 传递的参数一般只用来做协程控制、超时控制,状态跟踪等,当然一层层的封装用相同的 key 传递 value ,下一步是能取到的

什么叫『有什么开源程序,已经实现了这个?』
不是两行代码的事吗?你不是已经说明白了要怎么写吗?

当然这个逻辑看着就很有问题。

不过看起来像是 http 业务常用的中间件的逻辑,F1 直接塞就行了,C 处没必要做啥。反正 context 塞啥都行。

context 一般是用来传递 trace 的,业务逻辑上反正我是没用过

官方建议不要放一些 optional parameters
https://github.com/golang/go/blob/master/src/context/context.go#L573-L574

但如 6 楼所说,一些 trace 信息是可以塞进去的,我用来存放一些 token header user id

也不用怎么写,官方给了一个非常简单的写法,其实可以自己封装一下
https://github.com/golang/go/blob/master/src/context/context.go#L144-L158

大家都很强啊!

在Golang(Go语言)中,context.Context是一个用于跨多个goroutine传递超时、取消信号、截止日期等的重要组件,但它也包含一些潜在的问题,尤其是与context.Value相关的用法。关于为context.Value预留的“坑”及开源库的问题,以下是我的专业回复:

context.Value的潜在问题

context.Value允许在Context中存储键值对,用于在goroutine之间共享数据。然而,滥用context.Value会导致代码难以维护,因为它使得数据的流向变得不清晰,且容易在上下文中存储不必要的或生命周期不匹配的数据。

开源库与解决方案

虽然Go语言的标准库中并没有直接提供解决context.Value潜在问题的开源库,但开发者可以通过以下方式避免这些“坑”:

  1. 仅在必要时使用context.Value:避免在Context中存储过多或不必要的数据。
  2. 明确数据的生命周期:确保存储在Context中的数据与请求或操作的生命周期相匹配。
  3. 使用更明确的数据结构:考虑使用更明确的数据结构或传递参数的方式,而不是依赖Context来共享数据。

综上所述,虽然Go语言标准库没有提供直接的开源库来解决context.Value的潜在问题,但开发者可以通过谨慎使用context.Value并遵循最佳实践来避免这些“坑”。

回到顶部