修复“不应该在context.WithValue中使用基本类型字符串作为键”golint

时间:2016-11-30 14:50:23

标签: go golint

我正在使用ContextWithValue向处理此*http.request的后续函数传递一个uuid。此uuid已在授权标头中传递给REST调用以标识某个人。授权令牌已经过验证,需要访问以检查呼叫本身是否已获得授权。

我用过:

ctx := context.WithValue(r.Context(), string("principal_id"), *id)

但是高尔特抱怨道:

should not use basic type string as key in context.WithValue

可以用来检索此键的最佳选项是什么,而不是像简单字符串那样的基本类型?

4 个答案:

答案 0 :(得分:35)

只需使用密钥类型:

type key int

const (
    keyPrincipalID key = iota
    // ...
)

由于您已定义了单独的类型,因此它永远不会发生冲突。即使你有两个包,pkg1.key(0) != pkg2.key(0)

另请参阅:Go Blog about key collisions in context

答案 1 :(得分:1)

分享以上问题的简短答案。 GitHub Link 简而言之,context.WithValue()需要interface{}类型作为

我希望这会有所帮助。 谢谢。

答案 2 :(得分:0)

我通过执行以下操作达到了上述目的,并且感觉很干净

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'

并且可以打印出键的值,

fmt.Println("Key is:", ContextKeyDeleteCaller.String())

答案 3 :(得分:0)

最好使用 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

<块引用>

提供的键必须是可比较的,并且不应是字符串类型或任何其他内置类型,以避免使用上下文的包之间发生冲突。 WithValue 的用户应该定义他们自己的键类型。为避免在分配给接口时进行分配{},上下文键通常具有具体的类型 struct{}。或者,导出的上下文键变量的静态类型应该是指针或接口。