Go teams can drop ptr[T] helpers now that Go 1.26 lets new() take an expression
Go 1.26, released February 10, 2026, lets the built-in new() take an expression such as new(42) or new(time.Now()). Teams with ptr[T] or StringPtr helpers can preview a rewrite with go fix -diff -newexpr before deleting anything.
The Engineer · Build desk
![Illustration accompanying Go teams can drop ptr[T] helpers now that Go 1.26 lets new() take an expression](/_next/image?url=https%3A%2F%2Fmedia.theclarity.today%2Fnews%2Fheroes%2F2026-10-14%2Fbuild%2Fgo-teams-can-drop-ptr-t-helpers-now-that-go-1-26-lets-new-take-an-expression-1935752944-a9bb8032e360747d.png&w=3840&q=75)
Timeline: April 2021, Rob Pike opens golang/go#45624, 'spec: expression to create pointer to simple types', as an alternative to #9097; February 10, 2026, Go 1.26 is released and new accepts an expression; August 19, 2026, Go 1.27 is out with no change to new(expr), per the post.
| Date | Event | Claim |
|---|---|---|
| April 2021 | Rob Pike opens golang/go#45624, an alternative to #9097 | 2 |
| February 10, 2026 | Go 1.26 released; new now accepts an expression | 1 |
| August 19, 2026 | Go 1.27 out, no change to new(expr), per the post | 15 |
What happened
- The spec's Allocation section now defines new(x) as allocating a variable of x's type, initialized to the value of x.
- The change closes golang/go#45624, opened by Rob Pike in April 2021 as an alternative to older proposal #9097 and closed by Alan Donovan in October 2025.
- Go 1.26 also rewrote go fix as the home of Go's modernizers, and its newexpr analyzer targets the pointer-helper pattern.
Why it matters
- constraint Library authors pay for the cleanup in compatibility. Bumping the go directive sets a new minimum Go version for every importer, and the post says that is where the old helper still wins.
- decision Whether a shared pointer package can be deleted outright depends on its bodies. Only single-return helpers match the analyzer's rule, so any helper with extra logic stays a manual migration.
- capability An unset-versus-zero field can now be written inline. new(0) gives a non-nil pointer to 0, which omitempty keeps, so no function is needed to get "retries":0 into the JSON.
The helper existed because Go will not take the address of a constant or a call result. &42 and &time.Now() do not compile [6]. Go also has no Optional[T], so a field that must tell absent from zero is usually a pointer [7]. With omitempty, a nil pointer is dropped and a non-nil pointer to 0 is kept, so a Retries field set to a pointer to 0 serializes as "retries":0 [10]. The Go 1.26 release notes, as the post quotes them, call the feature "particularly useful when working with serialization packages such as encoding/json or protocol buffers that use a pointer to represent an optional value." [8]
Everyone wrote the same function. The post lists proto.String and proto.Int64 in protobuf-go, ptr.To in k8s.io/utils and ToPtr in samber/lo [9]. The protobuf ones are a single line each [11]. Donovan signed off the issue with "All done, in only eleven years since #9097. ;-)" [3].
Until 1.26, new took only a type. Now it accepts an expression [1]. The post says the behavior matches the helper's [12]. new(int) still returns a pointer to 0, new(123) returns a pointer to 123, and both are *int [5].
The adoption cost is the language version. Either the module or, via a build constraint, the individual file must declare at least Go 1.26, so a go.mod that says go 1.25 needs go mod edit -go=1.26 [13]. That raises the minimum Go version for everyone who imports the module. The post calls that usually fine for an application and a decision for a library, and names the library as the first case where the old helper wins [14]. Go 1.27, out since August 19, 2026, changes nothing about new(expr), the post says, so either release works [15].
For call sites, go fix -diff -newexpr ./... previews the rewrite and go fix -newexpr ./... applies it [17]. The newexpr analyzer looks for "new-like" functions: exactly one parameter, not variadic, a single pointer result, and nothing in the body but return ¶m [18]. In the post author's reading of the source, a generic ptr[T] should qualify, because the match is on the parameter itself [19]. Any helper with a different body falls outside that definition [20].
The text available to us ends partway through the analyzer's description, so what newexpr does with the helper's own declaration is unconfirmed. The author hedges the headline claim: "you can likely delete most of it now, and go fix will do the bulk of the work." [21]
What to watch
- The full output of go tool fix help newexpr, which should show whether the fixer also removes the helper's own declaration.
- Whether protobuf-go, k8s.io/utils and samber/lo change their one-line pointer helpers.
- Which library maintainers raise their go directive to 1.26 and which keep the helper to hold a lower minimum.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence62
- Adoption
- Insufficient
- Hype gap+10
- Incentives
- Insufficient
- Confidence60
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
Go 1.26 was released on February 10, 2026. The built-in new now accepts an expression, not only a type; new(42) and new(time.Now()) compile.
- [2]
In April 2021 Rob Pike opened golang/go#45624, 'spec: expression to create pointer to simple types', as an alternative to an older proposal, #9097; Alan Donovan closed the issue in October 2025.
- [3]
Alan Donovan signed off the issue with the joke: "All done, in only eleven years since #9097. ;-)"
- [4]
The spec's Allocation section now reads: if the argument is an expression x, then new(x) allocates a variable of the type of x initialized to the value of x.
- [5]
new(int) still gives a pointer to 0; new(123) gives a pointer to 123; both are *int.
- [6]
You cannot take the address of a constant or of a function call's result, so &42 and &time.Now() do not compile.
- [7]
Go has no Optional[T]; when a field can be absent and absent has to mean something different from zero, the usual answer is a pointer.
- [8]
The Go 1.26 release notes describe the feature as "particularly useful when working with serialization packages such as encoding/json or protocol buffers that use a pointer to represent an optional value."
- [9]
The ecosystem shipped its own copies of the helper: proto.String and proto.Int64 in protobuf-go, ptr.To in k8s.io/utils, and ToPtr in samber/lo.
- [10]
omitempty drops a nil pointer but keeps a non-nil pointer to 0, so the JSON says "retries":0 instead of saying nothing.
- [11]
The protobuf helpers are a single line each: func String(v string) *string { return &v }.
- [12]
According to the post, the behavior of the built-in new(expr) is the same as the helper.
- [13]
For new(expr) to compile, the module (or the file, through a build constraint) has to declare Go 1.26 or later; if go.mod still says go 1.25, it must be bumped with go mod edit -go=1.26.
- [14]
Bumping the go directive raises the minimum Go version for anyone who imports the module. For an application that is usually fine; for a library it is a decision, and it is the first case where the old helper wins, according to the post.
- [15]
According to the post, Go 1.27 has been out since August 19, 2026, and its release notes make no change to new(expr), so either current release works.
- [16]
Go 1.26 rewrote go fix into the home of Go's modernizers, built on the same analysis framework as go vet; one of them, newexpr, targets the pointer-helper pattern.
- [17]
Alan Donovan's post on the Go blog shows the commands: go fix -diff -newexpr ./... to preview, go fix -newexpr ./... to apply, and go tool fix help newexpr for the analyzer's docs.
- [18]
According to the analyzer docs and source, newexpr finds 'new-like' functions: one non-variadic parameter, one pointer result, and a body that is a single return ¶m.
- [19]
The post's author, reading the source, says a generic ptr[T] should qualify too: the match is on the parameter itself rather than its type, and the call-site check carries a comment saying it is formulated that way 'to support generics.'
- [20]
A helper whose body is anything other than a single return ¶m falls outside the matching rule newexpr is described as using.
- [21]
The post says that if a codebase has a ptr[T], StringPtr, IntPtr or utils/pointer.go, "you can likely delete most of it now, and go fix will do the bulk of the work."
Get this ledger inside ChatGPT. Ask about any of our stories and the answer brings its figure, each claim’s verdict and the sources. Free, no account.
Sources
1 independent publisher whose own reporting we read for this story.
- dev.toGo 1.26 Lets new() Take an Expression. Delete Your Pointer Helpers
1 article · October 14, 2026
Topics and entities
Follow any of these and your For You feed starts watching them — no settings page required.
Topics
- Developer ToolingFollow
- Go languageFollow
- Code migration and rewritesFollow