user1243746
user1243746

Reputation:

Use of new vs var in Go

You have a function with an argument, a pointer to a type.

type bar struct{...}

func foo(arg *bar)

Is there any difference between:

var b bar
foo(&b)

and

b := new(bar)
foo(b)

The use of new creates an allocation.

Upvotes: 19

Views: 6376

Answers (4)

Izaak Dale
Izaak Dale

Reputation: 11

One assigns a nil pointer, the other assigns a pointer to a zero initialized struct. In a linked list style example:

type Node struct { 
  Data int
  Next *Node
}

Create a node in each of the mentioned ways

var node1 = new(Node)
var node2 *Node

Printing the variables gives

&{0 <nil>}
<nil>

This means that if you were to try to do this

fmt.Println(node1.Data)
fmt.Println(node2.Data)

The first will print out 0, the second will throw a nil pointer dereference exception and panic.

Upvotes: 1

zzzz
zzzz

Reputation: 91193

There are a differences in certain situations. new(T), as the name implies, returns a, well, new instance of type T, while var b T is a single instance, once and forever (err, actually until end of its lifetime == going out of scope, not reachable...).

Consider this loop

var b bar
for i := 0; i < 10; i++ {
    foo(&b)
}

vs

var b *bar
for i := 0; i < 10; i++ {
    b = new(b)
    foo(b)
}

In the later case, if foo for example stores its arg in some container, results in 10 instances of bar existing while the former case with only one - in variable b.

Another difference is in the performance. The variable b would be either a fully static global variable or will typically sit at a statically known offset in some function/method invocation record (a fancy name for usually a stack frame). new OTOH, if not optimized out by the compiler, is a memory allocator call. Such call will cost some nonzero time. If made in a loop and not actually necessary, then it can make noticeable slowdown of some code path.

Upvotes: -4

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382092

No, there is no difference, as, contrary to C, Go explicitly states that you can give a pointer to a locally created variable.

From the documentation :

Note that, unlike in C, it's perfectly OK to return the address of a local variable; the storage associated with the variable survives after the function returns

Upvotes: 17

VonC
VonC

Reputation: 1323045

Both should represent the same pointer to the same object initialized with the same default value.

The spec does mention:

After

type T struct { i int; f float64; next *T }
t := new(T)

the following holds:

t.i == 0
t.f == 0.0
t.next == nil

The same would also be true after

var t T

Also:

Taking the address of a composite literal (§Address operators) generates a pointer to a unique instance of the literal's value.

var pointer *Point3D = &Point3D{y: 1000}

Upvotes: 6

Related Questions