Go

What does this print? (context value keys)

Question 268MediumGo 1.22 to 1.25
type ctxKey string

func main() {
	ctx := context.WithValue(context.Background(), ctxKey("user"), "alice")
	ctx = context.WithValue(ctx, ctxKey("user"), "bob")
	child, cancel := context.WithCancel(ctx)
	defer cancel()

	fmt.Println(child.Value(ctxKey("user")))
	fmt.Println(child.Value("user"))
	fmt.Println(child.Value(ctxKey("missing")))
}

Output:

bob
<nil>
<nil>
  • bob: Value walks up from the node where you call it, and the nearest match wins. The second WithValue hides the first; it does not replace it, and "alice" is still stored further up the chain. The WithCancel layer passes Value calls straight to its parent.
  • <nil> for "user": the key is an untyped string constant that becomes string, while the stored key's dynamic type is ctxKey. Different types mean the interfaces are not equal.
  • <nil> for a missing key: Value never panics. It returns nil, so always use the comma-ok type assertion.

More on Context

All 35 Context questions