0. 概述
在编写 Go 语言代码的时候,context 是一个非常常见的元素。但是,有时在搭配其他库时,我知道 context 里面包含某些信息,但是却不知道这些信息在 context 中的具体 key 是什么,所以这个时候除了调试之外,将 context 之中的数据打印出来不妨是一个好的选择。
但是,找了一圈,似乎没有看到一些比较简单的方式,最后用了反射的方法将所有的 context key 和 value 提取出来。
1. 代码
[[email protected]]# cat query_context.go
func TestContextPrint(t *testing.T) {
var ctx = context.Background()
ctx = context.WithValue(ctx, "hello", "world")
ctx = context.WithValue(ctx, "世界", "你好")
printContextInternals(ctx, false)
t.Fail()
}
func printContextInternals(ctx context.Context, inner bool) {
contextValues := reflect.ValueOf(ctx).Elem()
contextKeys := reflect.TypeOf(ctx).Elem()
if !inner {
fmt.Printf("\nFields for %s.%s\n", contextKeys.PkgPath(), contextKeys.Name())
}
var keys []string
if contextKeys.Kind() == reflect.Struct {
for i := 0; i < contextValues.NumField(); i++ {
reflectValue := contextValues.Field(i)
reflectValue = reflect.NewAt(reflectValue.Type(), unsafe.Pointer(reflectValue.UnsafeAddr())).Elem()
reflectField := contextKeys.Field(i)
if reflectField.Name == "Context" {
printContextInternals(reflectValue.Interface().(context.Context), true)
} else {
if reflectField.Name == "key" {
keys = append(keys, reflectValue.Interface().(string))
}
}
}
}
for _, key := range keys {
fmt.Printf("ctx.%s = %+v\n", key, ctx.Value(key))
}
}