Last week we saw the potential dangers of context key collisions. Today let’s look at how to avoid this problem.
The GoDoc we looked at last week gave us a clue:
// packages should define keys as an unexported type to avoid // collisions.
Let’s dive into what this is suggesting, and why it works.
First: context.WithValue accepts any comparable type as a key. This includes custom types. And by using a custom type that’s unexported, we can ensure that no other package uses our keys.
package private
type key string
var myUnexportedKey = key("key")
/* .. later .. */
ctx = context.WithValue(ctx, myUnexportedKey, "value")
Now other packages can create keys all day long with the underlying value of "key", but it will never match your key, because you’ve used your custom type, which is distinct from all others, and no other package can create a value using that type. Woot!