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.
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
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}
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.
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.
new. Also, please let me know which existing Go compiler(s) use that alternative. Thanks in advance. I realize the specs don't talk about stack or heap. That doesn't rule out talking about how the implementation works, especially if it aids to understanding. See also: research.swtch.com/godatavar b bar; ptrb := &b. The two ways he listed are identical according to the spec. You are allowed to talk about the implementation if you mention it is implementation dependent. However, you are wrong about the implementation. Both gc and gccgo will allocate them to the heap in both cases. In both cases the escape analysis forces them to put the variable on the heap.var b bar inside the loop in the first example, it would do the exact same thing as the second example. This is what the OP asked in the first place.
&Variablevsnew(Type)when passed to a pointer type taking function. 10990174 doesn't ask nor answer that.