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

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

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

问题

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

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

如何使用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:

  1. // Sample program to show how to store and retrieve
  2. // values from a context.
  3. package main
  4. import (
  5. "context"
  6. "fmt"
  7. )
  8. // TraceID represents the trace id.
  9. type TraceID string
  10. // TraceIDKey is the type of value to use for the key. The key is
  11. // type specific and only values of the same type will match.
  12. type TraceIDKey int
  13. func main() {
  14. // Create a traceID for this request.
  15. traceID := TraceID("f47ac10b-58cc-0372-8567-0e02b2c3d479")
  16. // Declare a key with the value of zero of type userKey.
  17. const traceIDKey TraceIDKey = 0
  18. // Store the traceID value inside the context with a value of
  19. // zero for the key type.
  20. ctx := context.WithValue(context.Background(), traceIDKey, traceID)
  21. // Retrieve that traceID value from the Context value bag.
  22. if uuid, ok := ctx.Value(traceIDKey).(TraceID); ok {
  23. fmt.Println("TraceID:", uuid)
  24. }
  25. // Retrieve that traceID value from the Context value bag not
  26. // using the proper key type.
  27. if _, ok := ctx.Value(0).(TraceID); !ok {
  28. fmt.Println("TraceID Not Found")
  29. }
  30. }

<hr>

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

答案1

得分: 4

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

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. )
  6. type contextKey int
  7. const (
  8. traceIDKey contextKey = iota
  9. aFunctionWhyNot
  10. )
  11. func main() {
  12. // 为这个请求创建一个 traceID。
  13. traceID := "f47ac10b-58cc-0372-8567-0e02b2c3d479"
  14. // 使用零值为键类型,在上下文中存储 traceID 值。
  15. ctx := context.WithValue(context.Background(), traceIDKey, traceID)
  16. // 从上下文值中检索 traceID 值。
  17. if uuid, ok := ctx.Value(traceIDKey).(string); ok {
  18. fmt.Println("TraceID:", uuid)
  19. }
  20. // 或者一个函数
  21. ctx = context.WithValue(ctx, aFunctionWhyNot, func() { fmt.Println("lol, I'm a function on a context") })
  22. // 可以调用它
  23. if f, ok := ctx.Value(aFunctionWhyNot).(func()); ok {
  24. f()
  25. }
  26. }

希望对你有帮助!

英文:

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:

  1. package main
  2. import (
  3. &quot;context&quot;
  4. &quot;fmt&quot;
  5. )
  6. type contextKey int
  7. const (
  8. traceIDKey contextKey = iota
  9. aFunctionWhyNot
  10. )
  11. func main() {
  12. // Create a traceID for this request.
  13. traceID := &quot;f47ac10b-58cc-0372-8567-0e02b2c3d479&quot;
  14. // Store the traceID value inside the context with a value of
  15. // zero for the key type.
  16. ctx := context.WithValue(context.Background(), traceIDKey, traceID)
  17. // Retrieve that traceID value from the Context value bag.
  18. if uuid, ok := ctx.Value(traceIDKey).(string); ok {
  19. fmt.Println(&quot;TraceID:&quot;, uuid)
  20. }
  21. // Or a function
  22. ctx = context.WithValue(ctx, aFunctionWhyNot, func() { fmt.Println(&quot;lol, I&#39;m a function on a context&quot;) })
  23. // Call it maybe
  24. if f, ok := ctx.Value(aFunctionWhyNot).(func()); ok {
  25. f()
  26. }
  27. }

答案2

得分: 2

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

  1. type cancelFuncKeyType struct{}
  2. var cancelFuncKey = cancelFuncKeyType{}
  3. ...
  4. newctx := context.WithValue(oldctx, cancelFuncKey, cancelFunc)
  5. cFunc := newctx.Value(cancelFuncKey).(context.CancelFunc)
英文:

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

  1. type cancelFuncKeyType struct{}
  2. var cancelFuncKey =cancelFuncKeyType{}
  3. ...
  4. newctx:=context.WithValue(oldctx,cancelFuncKey,cancelFunc)
  5. 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:

确定