How do you get a pointer to a literal value generically? Compare a Ptr[T] helper with Go 1.26 new(expr).
Question 147MediumGo 1.22 to 1.25
Optional fields in API structs (JSON, protobuf, AWS SDK) are often pointers, and &42 or &"x" is not valid Go. Before generics every library shipped aws.String, proto.Int32 and so on. With generics a single helper covers every type:
func Ptr[T any](v T) *T { return &v } // v escapes to the heap
type Req struct {
Limit *int
Name *string
}
r := Req{Limit: Ptr(10), Name: Ptr("go")}
// Go 1.26+: the built-in new accepts an expression
r2 := Req{Limit: new(10), Name: new("go")}
fmt.Println(*r.Limit, *r2.Name) // 10 go
Ptr(10)infersT = intfrom the untyped constant's default type. For another type, writePtr[int64](10)orPtr(int64(10)).- Each call returns a pointer to a fresh copy, so mutating
*pnever affects the caller's variable. - Go 1.26 extended
newso thatnew(expr)allocates a variable initialised to the value ofexpr. On Go 1.26+ this makes the helper unnecessary. On 1.18-1.25 the genericPtris the idiom. - The inverse,
Deref[T any](p *T, def T) T, is the usual companion for reading optional fields safely.
More on Generics
- Q145What does this print? (
%Tand reflection on generic types) - Q146Write a generic fan-in
Mergefor channels. What are the concurrency pitfalls?