context包 WithValue(ctx, key ,val) 的key参数应该是非导出的内置类型, 如何理解?

context包 WithValue函数, 官方写了大量关于key应该是非导出的, 非go内置的的类型. 官方文档看了好几遍, 没明白强调key的类型的具体意义. 故求问.

共 2 个回复



// WithValue returns a copy of parent in which the value associated with key is
// val.
// Use context Values only for request-scoped data that transits processes and
// APIs, not for passing optional parameters to functions.
// 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.
func WithValue(parent Context, key, val interface{}) Context {
    if key == nil {
        panic("nil key")
    if !reflect.TypeOf(key).Comparable() {
        panic("key is not comparable")
    return &valueCtx{parent, key, val}

// A valueCtx carries a key-value pair. It implements Value for that key and
// delegates all other calls to the embedded Context.
type valueCtx struct {
    key, val interface{}

func (c *valueCtx) String() string {
    return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)

func (c *valueCtx) Value(key interface{}) interface{} {
    if c.key == key {
        return c.val
    return c.Context.Value(key)


package main

import (

func main() {
    type myInt int
    i := myInt(1)
    fmt.Println(1 == i)     // true
    fmt.Println(compare(i)) // false
    fmt.Println(compare(1)) // true

func compare(key interface{}) bool {
    return 1 == key


# 0


“1 :

十分感谢, 明白了;

// 关于GC ,我把collisions 看成collection

# 1