v0.2.5: Empty-struct Context Keys
Former Best Practice was to use an unexported type for context Value
keys, in order to ensure proper encapsulation of the values (so third-party or second-party users cannot interfere with value storage). This allowed one to use a single context key type of concrete-type int
, which would enumerate the context keys, and interface
values would store that int
value directly, with a type attached.
However, in go1.4
, changes were made to how interfaces were implemented, and it was made that all values held by an interface were held by reference (as a pointer). This meant that now context key values would have to be allocated onto the heap, and the constant enum value stored there.
Best practice now, is to use a struct{}
type for each separate key. Since all struct{}
values may point to the same piece of memory (as they are 0-length types), this means that the pointer value stored in the interface does not require an allocation to store. The type information is then used alone to identify the specific usage. This avoids extra allocations just to store constant values in the heap.
Example of two differently typed struct{}
values existing at the same point in memory: https://play.golang.org/p/mvzxtRHKCrQ