Go

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) infers T = int from the untyped constant's default type. For another type, write Ptr[int64](10) or Ptr(int64(10)).
  • Each call returns a pointer to a fresh copy, so mutating *p never affects the caller's variable.
  • Go 1.26 extended new so that new(expr) allocates a variable initialised to the value of expr. On Go 1.26+ this makes the helper unnecessary. On 1.18-1.25 the generic Ptr is the idiom.
  • The inverse, Deref[T any](p *T, def T) T, is the usual companion for reading optional fields safely.

More on Generics

All 36 Generics questions