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!