Go
golang

contextパッケージを使用して値の受け渡しを行う際のkey指定

contextパッケージを使用して値の受け渡しを行う際のkey指定

context.WithValue()の第二引数keyにstring型を指定した場合、
golintによって警告される。

警告内容はshould not use basic type string as key in 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. ...

上記によるとパッケージ間での衝突を避けるため、keyに対しては独自の型を
定義するべし、とのこと。1

解消方法については以下のようにすればよさそう。

type key int

const (
    stringKey key = iota
)

上記のように宣言した上で、引数にはstringKeyを指定してやれば良い。

contextパッケージのソース内に例があった2ため、そちらをメモとして
載せておく。

// User is the type of value stored in the Contexts.
type User struct {...}

type key int

var userKey key

// NewContext returns a new Context that carries value u.
func NewContext(ctx context.Context, u *User) context.Context {
    return context.WithValue(ctx, userKey, u)
}

// FromContext returns the User value stored in ctx, if any.
func FromContext(ctx context.Context) (*User, bool) {
    u, ok := ctx.Value(userKey).(*User)
    return u, ok
}

参考記事


  1. こちらで詳しく説明されていた。勉強になります。Golangのcontext.Valueの使い方 | SOTA 

  2. go/context.go at go1.10.2 · golang/go