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.