英文:
Pointer to a struct (or lack thereof)
问题
假设我定义了这个结构体:
type Vertex struct {
X, Y float64
}
现在,在Go语言中,可以这样使用它:
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
函数中后面使用了指针。但是为什么当我不使用指针直接在结构体实例上调用Abs()
时,程序不会报错呢?
英文:
Let's say I have defined this struct:
type Vertex struct {
X, Y float64
}
now it's perfectly legal Go to use it like this:
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())
}
but it's also ok not to use a pointer:
func main() {
v := Vertex{3, 4}
fmt.Println(v.Abs())
}
The results in both cases is the same, but how are they different, internally? Does the use of pointer makes the program run faster?
PS. I get it that the Abs()
function needs a pointer as a receiver. That explains the reason why a pointer has been used later in the main function. But why doesn't the program spit out an error when I don't use a pointer and directly call Abs()
on a struct instance?
答案1
得分: 3
为什么在我不使用指针直接在结构体实例上调用Abs()
时,程序没有报错?
因为你可以获取结构体实例的指针(地址)。
正如在《Golang中的指针接收器和值接收器是什么意思?》中所提到的:
Go会自动对指针进行取址和自动解引用(在大多数情况下),所以
m := MyStruct{}; m.DoOtherStuff()
仍然可以工作,因为Go会自动为你执行(&m).DoOtherStuff()
。
正如《在Golang中不要被指针和非指针方法接收器搞混》或《Go 101: 指针方法和值方法》所示,使用指针接收器(v *Vertex)
可以避免拷贝,因为Go通过值传递一切。
与方法调用一样,使用指针接收器的非接口方法的引用将自动获取该值的地址:
t.Mp
等同于(&t).Mp
。
英文:
> why doesn't the program spit out an error when I don't use a pointer and directly call Abs()
on a struct instance?
Because you can get the pointer to (address of) a struct instance.
As mentioned in "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.
As illustrated by "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.
The 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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论