指向结构(或缺少结构)的指针
Pointer to a struct (or lack thereof)
假设我已经定义了这个结构:
type Vertex struct {
X, Y float64
}
现在它是完全合法的去像这样使用它:
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3, 4}
fmt.Println(v.Abs())
}
不过不用指针也可以:
func main() {
v := Vertex{3, 4}
fmt.Println(v.Abs())
}
两种情况下的结果是相同的,但它们在内部有何不同?使用指针会使程序运行更快吗?
PS。我知道 Abs()
函数需要一个指针作为接收者。这就解释了为什么稍后在 main 函数中使用指针的原因。但是为什么我不使用指针,直接在struct实例上调用Abs()
,程序没有吐错呢?
why doesn't the program spit out an error when I don't use a pointer and directly call Abs()
on a struct instance?
因为您可以获得指向结构实例(的地址)的指针。
如“What do the terms pointer receiver and value receiver mean in Golang?”中所述
Go will auto address and auto-dereference pointers (in most cases) so m := MyStruct{}; m.DoOtherStuff()
still works since Go automatically does (&m).DoOtherStuff()
for you.
如“Don't Get Bitten by Pointer vs Non-Pointer Method Receivers in Golang" or "Go 101: Methods on Pointers vs. Values", using a pointer receiver (v *Vertex)
is great to avoid copy, since Go passes everything by value所示。
spec mentions (Method values):
As with method calls, a reference to a non-interface method with a pointer receiver using an addressable value will automatically take the address of that value: t.Mp
is equivalent to (&t).Mp
.
假设我已经定义了这个结构:
type Vertex struct {
X, Y float64
}
现在它是完全合法的去像这样使用它:
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3, 4}
fmt.Println(v.Abs())
}
不过不用指针也可以:
func main() {
v := Vertex{3, 4}
fmt.Println(v.Abs())
}
两种情况下的结果是相同的,但它们在内部有何不同?使用指针会使程序运行更快吗?
PS。我知道 Abs()
函数需要一个指针作为接收者。这就解释了为什么稍后在 main 函数中使用指针的原因。但是为什么我不使用指针,直接在struct实例上调用Abs()
,程序没有吐错呢?
why doesn't the program spit out an error when I don't use a pointer and directly call
Abs()
on a struct instance?
因为您可以获得指向结构实例(的地址)的指针。
如“What do the terms pointer receiver and value receiver mean in Golang?”中所述
Go will auto address and auto-dereference pointers (in most cases) so
m := MyStruct{}; m.DoOtherStuff()
still works since Go automatically does(&m).DoOtherStuff()
for you.
如“Don't Get Bitten by Pointer vs Non-Pointer Method Receivers in Golang" or "Go 101: Methods on Pointers vs. Values", using a pointer receiver (v *Vertex)
is great to avoid copy, since Go passes everything by value所示。
spec mentions (Method values):
As with method calls, a reference to a non-interface method with a pointer receiver using an addressable value will automatically take the address of that value:
t.Mp
is equivalent to(&t).Mp
.