【Go】初识Context与Context键值对的可能情况
Prologue
- 写代码的时候,遇到需要从context中获得value的情况。
- 但是写的时候,会忽视可能的边界条件,导致panic。
初识Context
Context定义
-
Context是个interface。
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}
几种Context
context.Background
:这个返回的是一个empty, non-nil 的Context, 里面是没有value的。- 返回的是
emptyCtx
。
- 返回的是
context.WithValue
:这个函数返回的是一个有key-value的Context。- 返回的是一个
valueCtx
的指针。
- 返回的是一个
- 其他Context
- cancelCtx:可能被cancel的context。
- timerCtx:带计时器和截止日期的cancelCtx。
测试
代码
package main
import (
"context"
"fmt"
)
const KEY = "myKey"
func f(ctx context.Context){
val := ctx.Value(KEY)
v, ok := val.(string)
if ok{
fmt.Println("get val:", v)
}else{
fmt.Println("failed")
}
}
func main() {
// nil ctx
// f(nil) will panic
// empty ctx, no val
ctx := context.Background()
f(ctx)
// ctx that has val
ctx = context.WithValue(ctx, KEY, "my value")
f(ctx)
}
结果
-
panic: runtime error: invalid memory address or nil pointer dereference
-
failed get val: my value
分析
- ctx传入nil的时候会panic
panic: runtime error: invalid memory address or nil pointer dereference
- ctx传入一个emptyCtx的时候
- 断言判断会失败,ok为false。
- 不会panic。
- ctx传入一个有value的ctx时
- 断言判断成功,获得value。