测试代码如下:
package practice
import (
"context"
"log"
//"fmt"
"time"
)
func g1_1(ctx context.Context){
log.Println(ctx.Value("key1"))
ctx_b := context.Background()
log.Println(ctx_b.Value("key1"))
}
func g1(ctx context.Context){
log.Println(ctx.Value("key1"))
ctx1 := context.WithValue(ctx, "key1", "v1_g1")
go g1_1(ctx1)
}
func g2(ctx context.Context){
log.Println(ctx.Value("key1"))
ctx1 := context.WithValue(ctx, "key1", "v1_g2")
go g1_1(ctx1)
}
func MyContext(){
log.SetFlags(log.LstdFlags | log.Lshortfile)
ctx := context.Background()
log.Printf("%+v
", ctx)
ctx1 := context.WithValue(context.Background(), "key1", "v1")
log.Println(ctx1.Value("key1"))
go g1(ctx1)
go g2(ctx1)
time.Sleep(time.Duration(5)*time.Second)
}
打印结果如下:
2020/05/14 20:50:06 context_t.go:31: context.Background
2020/05/14 20:50:06 context_t.go:34: v1
2020/05/14 20:50:06 context_t.go:23: v1
2020/05/14 20:50:06 context_t.go:17: v1
2020/05/14 20:50:06 context_t.go:11: v1_g2
2020/05/14 20:50:06 context_t.go:13: <nil>
2020/05/14 20:50:06 context_t.go:11: v1_g1
2020/05/14 20:50:06 context_t.go:13: <nil>
我的理解:
- context.WithValue()创建出新的context后,相当于一颗树上开出新的分支
- 因此,不会像全局变量一样存在全局竞争。一个context可以用于向下级树传递值。
- 没办法通过类似parent的方法获得树的上级节点。
- 调用context.Background()始终是根节点。
还是比较赞同这篇文章的说法:Golang Context 是好的设计吗?
一旦代码中某处用到了Context,传递Context变量(通常作为函数的第一个参数)会像病毒一样蔓延在各处调用它的地方。