Also perform minor cleanups on the ctxkey package itself.
Provide guidance on when to use ctxkey.Key[T] over ctxkey.New.
Also, allow for interface kinds because the value wrapping trick
also happens to fix edge cases with interfaces in Go.
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
The lack of type-safety in context.WithValue leads to the common pattern
of defining of package-scoped type to ensure global uniqueness:
type fooKey struct{}
func withFoo(ctx context, v Foo) context.Context {
return context.WithValue(ctx, fooKey{}, v)
}
func fooValue(ctx context) Foo {
v, _ := ctx.Value(fooKey{}).(Foo)
return v
}
where usage becomes:
ctx = withFoo(ctx, foo)
foo := fooValue(ctx)
With many different context keys, this can be quite tedious.
Using generics, we can simplify this as:
var fooKey = ctxkey.New("mypkg.fooKey", Foo{})
where usage becomes:
ctx = fooKey.WithValue(ctx, foo)
foo := fooKey.Value(ctx)
See https://go.dev/issue/49189
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>