我正在传递一个uuid使用Context和WithValue处理它的后续函数*http.request.此uuid已在授权标头中传递给REST调用以标识某个人.验证授权令牌并且需要可访问以检查呼叫本身是否已被授权.
我用了:
ctx := context.WithValue(r.Context(), string("principal_id"), *id)
Run Code Online (Sandbox Code Playgroud)
但是高尔特抱怨道:
should not use basic type string as key in context.WithValue
Run Code Online (Sandbox Code Playgroud)
什么是可用于检索此键的最佳选项,该键不是像简单字符串那样的基本类型?
Ain*_*r-G 46
只需使用密钥类型:
type key int
const (
keyPrincipalID key = iota
// ...
)
Run Code Online (Sandbox Code Playgroud)
由于您已经定义了一个单独的类型,因此它永远不会发生冲突.即使你有两个包,pkg1.key(0) != pkg2.key(0).
另请参阅:在上下文中关于关键冲突的博客.
F56*_*566 22
使用类型struct{}更好。
type ctxKey struct{} // or exported to use outside the package
ctx = context.WithValue(ctx, ctxKey{}, 123)
fmt.Println(ctx.Value(ctxKey{}).(int) == 123) // true
Run Code Online (Sandbox Code Playgroud)
参考: https: //golang.org/pkg/context/#WithValue
提供的键必须是可比较的,并且不应是字符串类型或任何其他内置类型,以避免使用上下文的包之间发生冲突。WithValue 的用户应该定义自己的键类型。为了避免在分配给 interface{} 时进行分配,上下文键通常具有具体类型 struct{}。或者,导出的上下文键变量的静态类型应该是指针或接口。
我通过执行以下操作实现了上述目标,并且感觉它非常干净
package util
import "context"
type contextKey string
func (c contextKey) String() string {
return string(c)
}
var (
// ContextKeyDeleteCaller var
ContextKeyDeleteCaller = contextKey("deleteCaller")
// ContextKeyJobID var
ContextKeyJobID contextKey
)
// GetCallerFromContext gets the caller value from the context.
func GetCallerFromContext(ctx context.Context) (string, bool) {
caller, ok := ctx.Value(ContextKeyDeleteCaller).(string)
return caller, ok
}
// GetJobIDFromContext gets the jobID value from the context.
func GetJobIDFromContext(ctx context.Context) (string, bool) {
jobID, ok := ctx.Value(ContextKeyJobID).(string)
return jobID, ok
}
Run Code Online (Sandbox Code Playgroud)
..然后设置上下文,
ctx := context.WithValue(context.Background(), util.ContextKeyDeleteCaller, "Kafka Listener")
Run Code Online (Sandbox Code Playgroud)
..从上下文中获取价值,
caller, ok := util.GetCallerFromContext(ctx)
if !ok {
dc.log.Warn("could not get caller from context")
}
fmt.Println("value is:", caller) // will be 'Kafka Listener'
Run Code Online (Sandbox Code Playgroud)
并且可以通过这样做打印出键的值,
fmt.Println("Key is:", ContextKeyDeleteCaller.String())
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9856 次 |
| 最近记录: |