• 【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
      

    分析

    1. ctx传入nil的时候会panic
      • panic: runtime error: invalid memory address or nil pointer dereference
    2. ctx传入一个emptyCtx的时候
      • 断言判断会失败,ok为false。
      • 不会panic。
    3. ctx传入一个有value的ctx时
      • 断言判断成功,获得value。
  • 相关阅读:
    java垃圾回收算法和垃圾收集器
    (转)数据库ACID特性
    数据库范式
    (转)java Exception层次结构详解
    java Thread方法解析: sleep join wait notify notifyAll
    (转)java反编译i++和++i问题
    (转)git使用教程
    (转)java位运算
    (转)原码、反码、补码
    [翻译]如何编写GIMP插件(一)
  • 原文地址:https://www.cnblogs.com/xuwanwei/p/15118778.html
Copyright © 2020-2023  润新知