How to store a value of type context.CancelFunc using context.WithValue()?

huangapple go评论74阅读模式
英文:

How to store a value of type context.CancelFunc using context.WithValue()?

问题

要在ctx中存储string类型的数据,需要使用类型定义来定义键和值,如下所示:

    // 用于表示追踪ID的类型
    type TraceID string
    
    // 用于键的类型定义。键是特定类型的,只有相同类型的值才能匹配。
    type TraceIDKey int
    
    func main() {
    
    	// 为此请求创建一个追踪ID。
    	traceID := TraceID("f47ac10b-58cc-0372-8567-0e02b2c3d479")
    
    	// 声明一个值为零的键,类型为TraceIDKey。
    	const traceIDKey TraceIDKey = 0
    
    	// 使用键类型的零值将traceID值存储在上下文中。
    	ctx := context.WithValue(context.Background(), traceIDKey, traceID)
    
    	// 从上下文值中检索该追踪ID值。
    	if uuid, ok := ctx.Value(traceIDKey).(TraceID); ok {
    		fmt.Println("TraceID:", uuid)
    	}
    
    	// 不使用正确的键类型从上下文值中检索该追踪ID值。
    	if _, ok := ctx.Value(0).(TraceID); !ok {
    		fmt.Println("TraceID Not Found")
    	}
    }

如何使用context.WithValue() API存储context.CancelFunc类型的值?

英文:

To store string type data in ctx, type definitions need to be used for both key & value, as shown below:

    // 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")
    	}
    }

<hr>

How to store a value of type context.CancelFunc using context.WithValue() api?

答案1

得分: 4

你部分正确。你应该使用自定义类型作为上下文键,而不是使用内置类型,以确保避免冲突。这个类型应该是未导出的,除非你希望其他包能够读取/写入你的上下文键。然而,值可以是任何你喜欢的类型,例如:

package main

import (
	"context"
	"fmt"
)

type contextKey int

const (
	traceIDKey contextKey = iota
	aFunctionWhyNot
)

func main() {

	// 为这个请求创建一个 traceID。
	traceID := "f47ac10b-58cc-0372-8567-0e02b2c3d479"

	// 使用零值为键类型,在上下文中存储 traceID 值。
	ctx := context.WithValue(context.Background(), traceIDKey, traceID)

	// 从上下文值中检索 traceID 值。
	if uuid, ok := ctx.Value(traceIDKey).(string); ok {
		fmt.Println("TraceID:", uuid)
	}

	// 或者一个函数
	ctx = context.WithValue(ctx, aFunctionWhyNot, func() { fmt.Println("lol, I'm a function on a context") })

	// 可以调用它
	if f, ok := ctx.Value(aFunctionWhyNot).(func()); ok {
		f()
	}
}

希望对你有帮助!

英文:

You are partially correct. You should use a bespoke type for your context key rather than the builtin types to make collisions impossible. This type should be unexported unless you want other packages to be able to read/write your context key. However the value can be anything you like, eg:

package main

import (
	&quot;context&quot;
	&quot;fmt&quot;
)

type contextKey int

const (
	traceIDKey contextKey = iota
	aFunctionWhyNot
)

func main() {

	// Create a traceID for this request.
	traceID := &quot;f47ac10b-58cc-0372-8567-0e02b2c3d479&quot;

	// 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(&quot;TraceID:&quot;, uuid)
	}

	// Or a function
	ctx = context.WithValue(ctx, aFunctionWhyNot, func() { fmt.Println(&quot;lol, I&#39;m a function on a context&quot;) })

	// Call it maybe
	if f, ok := ctx.Value(aFunctionWhyNot).(func()); ok {
		f()
	}
}

答案2

得分: 2

你可以像存储其他任何值一样,将函数存储在上下文中:

type cancelFuncKeyType struct{}
var cancelFuncKey = cancelFuncKeyType{}

...
newctx := context.WithValue(oldctx, cancelFuncKey, cancelFunc)

cFunc := newctx.Value(cancelFuncKey).(context.CancelFunc)
英文:

You can store a function in the context the same way you store any other value:

type cancelFuncKeyType struct{}
var cancelFuncKey =cancelFuncKeyType{}

...
newctx:=context.WithValue(oldctx,cancelFuncKey,cancelFunc)


cFunc:=newctx.Value(cancelFuncKey).(context.CancelFunc)

huangapple
  • 本文由 发表于 2021年10月6日 00:37:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/69454253.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定