1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Go】context.WithValueでstringをキーに使うと怒られる?

Posted at

❗ エラーについて

Goで context.WithValue を使ってキーにstring型を指定すると、
以下のような警告が出ます。

should not use built-in type string as key for value; define your own type to avoid collisions (SA1029)

これは staticcheck によるコード品質向上のためのチェックの一つで、
「SA1029」というルールに該当します。

🤔 エラーの解説

なぜ string をキーにすると警告されるのか?

context.WithValue は内部的に key-value を持つツリー構造を作りますが、
キーの衝突があってもコンパイルエラーにならないという問題があります。

以下のように、複数の異なるパッケージで "traceID" という文字列をキーにしていた場合、
意図しない上書きや参照が起こる可能性があります。

ctx := context.WithValue(context.Background(), "traceID", 123)
value := ctx.Value("traceID") // 意図したものとは限らない

こうした衝突は静かに発生し、バグを見つけにくくします。

✅ 解決方法

解決策:独自の型を使う

Goではキーに使う値は何でもOKですが、
衝突を防ぐために「独自の型+ゼロ値(struct{})」を使うのが一般的です。

type traceIDKey struct{}

func SetTraceID(ctx context.Context, traceID int) context.Context {
	return context.WithValue(ctx, traceIDKey{}, traceID)
}

func GetTraceID(ctx context.Context) (int, bool) {
	val := ctx.Value(traceIDKey{})
	if id, ok := val.(int); ok {
		return id, true
	}
	return 0, false
}

🧠 なぜ空の構造体を使用するのか?

キーに string や int を使うと、それ自体がヒープに割り当てられる可能性があります。

またパッケージ間でキーを共有してしまうと、
予期せぬアクセスによってGCやデバッグのコストも上がります。

struct{} 型のキーは

  • ゼロサイズ
  • ユニーク性が高い(型が異なると別物)
  • ヒープに割り当てられにくい

といった理由から、パフォーマンスと安全性の両面で優れているとされています。

🧩 まとめ

  • context.WithValue のキーに string を使うと staticcheck に怒られる(SA1029)
  • 理由は キーの衝突によるバグの温床になるため
  • 解決策は「独自の unexported 型(例:**type traceIDKey struct{})」を定義すること
  • 空の構造体 struct{} は GC負荷も小さく、Goの公式にも推奨されている使い方

✅ おまけ(サンプルコード)

良ければハンズオンに使用していただければと!

package trace

import "context"

type traceIDKey struct{}

func SetTraceID(ctx context.Context, id int) context.Context {
	return context.WithValue(ctx, traceIDKey{}, id)
}

func GetTraceID(ctx context.Context) (int, bool) {
	val := ctx.Value(traceIDKey{})
	id, ok := val.(int)
	return id, ok
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?