Reputation:
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
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
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
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
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