修复 "should not use basic type string as key in context.WithValue" golint
Fix "should not use basic type string as key in context.WithValue" golint
我在使用 Context
和 WithValue
时将一个 uuid 传递给处理此 *http.request
的后续函数。此 uuid 已在授权 header 中传递给 REST 调用以识别人员。授权令牌已验证,需要可访问以检查调用本身是否已获得授权。
我用过:
ctx := context.WithValue(r.Context(), string("principal_id"), *id)
但是 golint 抱怨:
should not use basic type string as key in context.WithValue
可用于检索非基本类型(如简单字符串)的密钥的最佳选项是什么?
只需使用密钥类型:
type key int
const (
keyPrincipalID key = iota
// ...
)
既然你定义了一个单独的类型,它永远不会发生冲突。即使你有两个包,pkg1.key(0) != pkg2.key(0)
.
分享对上述问题的简要回答。
GitHub Link
简而言之,context.WithValue()
需要 interface{}
输入 keys 和 values.
希望对您有所帮助。
谢谢。
我是通过下面的方式实现的,感觉还挺干净的
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
}
..然后通过
设置上下文
ctx := context.WithValue(context.Background(), util.ContextKeyDeleteCaller, "Kafka Listener")
..从上下文中获取值,
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'
并且可以打印出key的值,
fmt.Println("Key is:", ContextKeyDeleteCaller.String())
使用类型 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
参考:https://golang.org/pkg/context/#WithValue
The provided key must be comparable and should not be of type string or any other built-in type to avoid collisions between packages using context. Users of WithValue should define their own types for keys. To avoid allocating when assigning to an interface{}, context keys often have concrete type struct{}. Alternatively, exported context key variables' static type should be a pointer or interface.
我在使用 Context
和 WithValue
时将一个 uuid 传递给处理此 *http.request
的后续函数。此 uuid 已在授权 header 中传递给 REST 调用以识别人员。授权令牌已验证,需要可访问以检查调用本身是否已获得授权。
我用过:
ctx := context.WithValue(r.Context(), string("principal_id"), *id)
但是 golint 抱怨:
should not use basic type string as key in context.WithValue
可用于检索非基本类型(如简单字符串)的密钥的最佳选项是什么?
只需使用密钥类型:
type key int
const (
keyPrincipalID key = iota
// ...
)
既然你定义了一个单独的类型,它永远不会发生冲突。即使你有两个包,pkg1.key(0) != pkg2.key(0)
.
分享对上述问题的简要回答。
GitHub Link
简而言之,context.WithValue()
需要 interface{}
输入 keys 和 values.
希望对您有所帮助。 谢谢。
我是通过下面的方式实现的,感觉还挺干净的
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
}
..然后通过
设置上下文ctx := context.WithValue(context.Background(), util.ContextKeyDeleteCaller, "Kafka Listener")
..从上下文中获取值,
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'
并且可以打印出key的值,
fmt.Println("Key is:", ContextKeyDeleteCaller.String())
使用类型 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
参考:https://golang.org/pkg/context/#WithValue
The provided key must be comparable and should not be of type string or any other built-in type to avoid collisions between packages using context. Users of WithValue should define their own types for keys. To avoid allocating when assigning to an interface{}, context keys often have concrete type struct{}. Alternatively, exported context key variables' static type should be a pointer or interface.