Go proposal: new(expr)
Part of the Accepted! series, explaining the upcoming Go changes in simple terms.
Allow the new
built-in to be called on expressions.
Ver. 1.26 • Language • High impact
Summary
Previously, you could only use the new
built-in with types:
p1 := new(int)
fmt.Println(*p1)
// 0
Now you can also use it with expressions:
// Pointer to a int variable with the value 42.
p := new(42)
fmt.Println(*p)
// 42
If the argument expr
is an expression of type T, then new(expr)
allocates a variable of type T, initializes it to the value of expr
, and returns its address, a value of type *T
.
Motivation
There's an easy way to create a pointer to a composite literal:
type Person struct { name string }
p := &Person{name: "alice"}
But no easy way to create a pointer to a value of simple type:
n := 42
p := &n
The proposal aims to fix this.
Description
The Allocation section of the language specification is updated as follows:
Allocation
The built-in function new
creates a new, initialized variable and returns a pointer to it. It accepts a single argument, which may be either an expression or a type.
➀ If the argument expr
is an expression of type T, or an untyped constant expression whose default type is T, then new(expr)
allocates a variable of type T, initializes it to the value of expr
, and returns its address, a value of type *T
.
➁ If the argument is a type T, then new(T)
allocates a variable initialized to the zero value of type T.
For example, new(123)
and new(int)
each return a pointer to a new variable of type int. The value of the first variable is 123, and the value of the second is 0.
➀ is the new part, ➁ already worked as described.
Examples
Pointer to a simple type:
// go 1.25
n := 42
p1 := &n
s := "go"
p2 := &s
// go 1.26
p1 := new(42)
s := "go"
p2 := new(s)
Pointer to a composite value:
// go 1.25
s := []int{11, 12, 13}
p1 := &s
type Person struct{ name string }
p2 := &Person{name: "alice"}
// go 1.26
p1 := new([]int{11, 12, 13})
type Person struct{ name string }
p2 := new(Person{name: "alice"})
Pointer to the result of a function call:
// go 1.25
f := func() string { return "go" }
v := f()
p := &v
// go 1.26
f := func() string { return "go" }
p := new(f())
Passing nil
is still not allowed:
// go 1.25 and go 1.26
p := new(nil)
// compilation error
Further reading
𝗣 45624 • 𝗖𝗟 704935, 704737, 704955, 705157
★ Subscribe to keep up with new posts.