gpt4 book ai didi

pointers - Go 中可以使用哪些指针?

转载 作者:IT王子 更新时间:2023-10-29 01:22:26 26 4
gpt4 key购买 nike

我想我明白什么是指针,但我不太明白什么时候使用它。
以下片段来自 "A Tour of Go" .
“*Vertex”和“&Vertex”的目的是什么?
我将它们替换为“Vertex”并且运行良好。

package main

import (
"fmt"
"math"
)

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 (v Vertex) SetX(x int) {
v.X = x
}

func main() {
v := Vertex{3, 4}
fmt.Println(v)
v.SetX(1)
fmt.Println(v)
}

您会注意到,这不会改变任何东西(严格来说,它改变了顶点的副本,但在大多数情况下这只是语义)! v 的值仍然是 {3,4}。尝试使用:

func (v *Vertex) SetX(x int) {
v.X = x
}

func main() {
v := &Vertex{3, 4}
fmt.Println(v)
v.SetX(1)
fmt.Println(v)
}

突然,它工作了,第二次打印 {1,4}。现在,如果您很好奇,您可以决定试验并将 v := &Vertex{3, 4} 更改为 v := Vertex{3, 4}。事实上,上面的代码片段仍然有效。奇怪的。同样,如果您将第二个代码段中的同一行更改为包含一个指针,它的工作方式也是相同的。

为什么? Go 有“透明”的指针。在其他具有显式指针值的语言(如 C 或 C++)中,您必须显式使用运算符 &* 来取消引用指针。 C 和 C++ 甚至具有特殊的语法,用于在字段访问和方法调用时追逐指针 v->SetX

无论好坏,Go 都会向您隐藏这一点。如果你有一个值并且需要调用一个指针方法,Go 会很乐意为你做 (&v).Method(),如果你需要取消引用来调用一个值方法,它会很乐意为你做 (*v).Method() 自动。这在大多数情况下都是正确的,有一些像 map 这样的极端情况不适用,但总的来说这是成立的。

那么,归根结底,什么时候应该在方法上使用指针接收器?答案确实是“大部分时间”。 Go Style Guide通常建议使用指针类型方法接收器,除非接收器是 mapfuncchan 的直接别名,它是一个不不需要重新 slice ,或者您正在对小的、不可变的数据类型进行优化(因为指针追踪比复制慢一点)。我要补充一点,您通常不应该使用指向指针的直接指针。

通常,当您不知道使用哪个时,请使用指针接收器。 99% 的时间使用指针会给您带来预期的行为,尤其是当您习惯使用 Python 或 C# 等语言时。相对而言,错误使用指针导致错误的情况相对较少,因为您的 Setter 方法实际上并未设置任何内容,因此出现错误的可能性比较大。

关于pointers - Go 中可以使用哪些指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24120789/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com