如何使用 context.WithValue() 存储 context.CancelFunc 类型的值?
Posted
技术标签:
【中文标题】如何使用 context.WithValue() 存储 context.CancelFunc 类型的值?【英文标题】:How to store a value of type context.CancelFunc using context.WithValue()? 【发布时间】:2021-11-25 22:58:18 【问题描述】:要将string
类型数据存储在ctx
中,key&value都需要使用类型定义,如下图:
// Sample program to show how to store and retrieve
// values from a context.
package main
import (
"context"
"fmt"
)
// TraceID represents the trace id.
type TraceID string
// TraceIDKey is the type of value to use for the key. The key is
// type specific and only values of the same type will match.
type TraceIDKey int
func main()
// Create a traceID for this request.
traceID := TraceID("f47ac10b-58cc-0372-8567-0e02b2c3d479")
// Declare a key with the value of zero of type userKey.
const traceIDKey TraceIDKey = 0
// Store the traceID value inside the context with a value of
// zero for the key type.
ctx := context.WithValue(context.Background(), traceIDKey, traceID)
// Retrieve that traceID value from the Context value bag.
if uuid, ok := ctx.Value(traceIDKey).(TraceID); ok
fmt.Println("TraceID:", uuid)
// Retrieve that traceID value from the Context value bag not
// using the proper key type.
if _, ok := ctx.Value(0).(TraceID); !ok
fmt.Println("TraceID Not Found")
如何使用context.WithValue()
api 存储context.CancelFunc
类型的值?
【问题讨论】:
遵循您用于存储 traceID 的模式。 您可以使用任何类型的键和值。我怀疑您是否需要在上下文中存储取消功能,这是一种设计气味。如果您描述了您的目标,也许我们可以提出更好的替代方案。 【参考方案1】:你是部分正确的。您应该为您的上下文键使用定制类型而不是内置类型,以使冲突变得不可能。这种类型应该不被导出,除非你希望其他包能够读/写你的上下文键。但是,该值可以是您喜欢的任何值,例如:
package main
import (
"context"
"fmt"
)
type contextKey int
const (
traceIDKey contextKey = iota
aFunctionWhyNot
)
func main()
// Create a traceID for this request.
traceID := "f47ac10b-58cc-0372-8567-0e02b2c3d479"
// Store the traceID value inside the context with a value of
// zero for the key type.
ctx := context.WithValue(context.Background(), traceIDKey, traceID)
// Retrieve that traceID value from the Context value bag.
if uuid, ok := ctx.Value(traceIDKey).(string); ok
fmt.Println("TraceID:", uuid)
// Or a function
ctx = context.WithValue(ctx, aFunctionWhyNot, func() fmt.Println("lol, I'm a function on a context") )
// Call it maybe
if f, ok := ctx.Value(aFunctionWhyNot).(func()); ok
f()
【讨论】:
【参考方案2】:您可以像存储任何其他值一样在上下文中存储函数:
type cancelFuncKeyType struct
var cancelFuncKey =cancelFuncKeyType
...
newctx:=context.WithValue(oldctx,cancelFuncKey,cancelFunc)
cFunc:=newctx.Value(cancelFuncKey).(context.CancelFunc)
【讨论】:
以上是关于如何使用 context.WithValue() 存储 context.CancelFunc 类型的值?的主要内容,如果未能解决你的问题,请参考以下文章