Context

作用

context 包的作用是在 goroutine 树中传递截止时间以及取消信号

context.go

context.go 在$GOROOT/src/context/文件中,该文件件包含了一个context的接口

type Context interface {
  Deadline() (deadline time.Time, ok bool)
  Done() <-chan struct{}
    Err() error
  Value(key interface{}) interface{}
}

四个实现类型emptyCtxcancelCtxtimerCtxvalueCtx

emptyCtx

type emptyCtx int

emptyCtx 就是一个int 类型,通过调用

contxt.Background() //初始化一个context

或者

contxt.TODO()  //初始化一个context,不止

cancelCtx

type cancelCtx struct {
  Context

  mu       sync.Mutex            // protects following fields
  done     chan struct{}         // created lazily, closed by first cancel call
  children map[canceler]struct{} // set to nil by the first cancel call
  err      error                 // set to non-nil by the first cancel call
}

cancelCtx 通过WithCancel() 方法来创建,其中children 是存储子context的

timerCtx

type timerCtx struct {
  cancelCtx     
  timer *time.Timer // Under cancelCtx.mu.
  deadline time.Time
}

通过以下两个方法来创建timerCtx

//指定截止日期,传入一个要取消的时间
func WithDeadline(parent Context, d time.Time)(Context, CancelFunc) 
//指定超时时间,传入一个超时时间,内部也是由WithDeadline 实现的,通过
// time.Now().Add(timeout)实现
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)

timerCtx 中包含了cancelCtx 结构体,所以可以传入一个cancelCtx 给timerctx,

valueCtx

type valueCtx struct {
  Context
  key, val interface{}
}

valueCtx 的作用是给context附带值。但是当传入的key 值类型和value 一样的,如下:

  var  keyA string = "one"
  ctx:=context.Background()
  ctx1,cancel1:=context.WithCancel(ctx)
  ctxA:=context.WithValue(ctx1,key1,"value1")
  var  keyB string = "one"
  ctxB:=context.WithValue(ctxA,keyB,"value2")

那么就会导致ctxB.Value(keyA) 获取值的时候会获取到 value2 这个值。因为

func (c *valueCtx) Value(key interface{}) interface{} {
  if c.key == key { //这里会比较key 如果相等直接就返回这个ctx的值,上面例子中ctxA 和ctxB 中存的是都是string 类型,值也一样,所以就返回了ctxB的值
    return c.val
  }
  return c.Context.Value(key)
}

Comment

您的电子邮箱地址不会被公开。 必填项已用 * 标注