[Golang] Context
文章目录
什么是context
Golang在1.7版本中引入了一个标准库的接口context,定义:
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{
}
Err() error
Value(key any) any
}
它定义了四个方法:
-
Deadline:设置context.Context被取消的时间,即截止日期
-
Done:返回一个只读channel,当Context到达截止日期时或被取消,这个channel就会被关闭,表示Context的链路结束,多次调用Done会返回同一个channel
-
Err:返回Context结束的原因,它只会在Done返回的channel被关闭时,才会返回非空的值;
- 情况1:Context被取消:返回Canceled
- 情况2:Context超时:返回DeadlineExceeded
-
Value:从context.Context中获取键对应的值,类似与map的get方法,对于同一个Context,多次调用Value并传入相同的key会返回相同的结果,如果没有对应的key就返回nil。
- 键值对通过
WithValue
方法写入
- 键值对通过
func WithValue(parent Context, key, val any) Context {
if parent == nil {
panic("cannot create context from nil parent")
}
if key == nil {
panic("nil key")
}
if !reflectlite.TypeOf(key).Comparable() {
panic("key is not comparable")
}
return &valueCtx{
parent, key, val}
}
创建context
创建根context
两种方法:
context.Background()
context.TODO()
两者没有什么太多的区别,都是创建根context,根context是一个空的context,不具备任何功能。
一般情况下,当前函数没有上下文作为入参,我们就使用context.Background()
创建一个根context作为起始的上下文向下传递。
创建context
根context被创建后,不具备任何功能,为了让context在程序中发挥作用,我们需要依靠包提供的With
系列函数来进行派生。
四个派生函数:
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
...}
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {
...}
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
...}
func WithValue(parent Context, key, va