In the gotour, there is a section: struct literals.
package main
import "fmt"
type Vertex struct {
X, Y int
}
var (
v1 = Vertex{1, 2} // has type Vertex
v2 = Vertex{X: 1} // Y:0 is implicit
v3 = Vertex{} // X:0 and Y:0
p = &Vertex{1, 2} // has type *Vertex
)
func main() {
fmt.Println(v1, p, v2, v3)
}
What's the difference between a struct with an ampersand and the one without? I know that the ones with ampersands point to the same reference, but why should I use them over the regular ones?
var p = &Vertex{} // why should I use this
var c = Vertex{} // over this
It's true that p
(&Vertex{}
) has type *Vertex
and that c
(Vertex{}
) has type Vertex
.
However, I don't believe that statement really answers the question of why one would choose one over the other. It'd be kind of like answering the question "why use planes over cars" with something like "planes are winged, cars aren't." (Obviously we all know what wings are, but you get the point).
But it also wouldn't be very helpful to simply say "go learn about pointers" (though I think it is a really good idea to so nonetheless).
How you choose basically boils down to the following.
Realize that &Vertex{}
and Vertex{}
are fundamentally initialized in the same way.
What makes one more useful and performant than the other is determined by how they are used in the program.
"Do I want a pointer to the struct (p
), or just the struct (c
)?"
&
operator (e.g. &c
); you can dereference a pointer to get the value using *
(e.g. *p
)
*p
or &c
Vertex{}
or &Vertex{}
?
Vertex
given in your example, I'd choose Vertex{}
to a get a simple value object.Vertex
in the example is pretty small in terms of size. Copying is cheap.Vertex
doesn't really contain anything worth mutating (just return/create a new Vertex
when needed).&Struct{}
Struct
has a member caching some state that needs to be changed inside the original object itself.Struct
is huge, and you've done enough profiling to determine that the cost of copying is significant.
struct
s small, it's just good practice. v := Struct{}
v2 := v // Copy happens
v := &Struct{}
v2 := v // Only a pointer is copied
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With