首页 > 后端开发 > Golang > Go 指针:为什么我似乎可以向我的方法传递值或指针?

Go 指针:为什么我似乎可以向我的方法传递值或指针?

Linda Hamilton
发布: 2024-11-10 13:57:02
原创
776 人浏览过

 Go Pointers: Why Does It Seem Like I Can Pass Either a Value or a Pointer to My Method?

Go 指针:揭秘指针语义

指针是 Go 编程中的一个基本概念,它可以通过引用来操作内存地址和值。虽然指针与其他编程语言有相似之处,但 Go 的指针语义可能是独特的,可能会给初学者带来困惑。

考虑以下代码:

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())
}
登录后复制

代码片段定义了一个 Vertex 结构体和func (v *Vertex) Abs() 方法,计算顶点坐标的绝对值。通过将方法接收器声明为指针 *Vertex,我们表明该方法对指向 Vertex 值的指针进行操作。

如果我们将代码修改如下:

func (v Vertex) Abs() float64 {
    [...]
    v := &Vertex{3, 4}
}
登录后复制

其中接收者不再是一个指针,而是一个值(Vertex),我们将得到相同的结果。这样做的原因有两个:

方法派生:Go 允许从具有值接收器的方法派生出具有指针接收器的方法。这意味着方法 func (v Vertex) Abs() 自动生成一个额外的方法实现:

func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X+v.Y*v.Y) }
func (v *Vertex) Abs() float64 { return Vertex.Abs(*v) } // GENERATED METHOD
登录后复制

当你调用 v.Abs() 时,其中 v 不是指针,编译器会自动查找并使用生成的方法。

自动取地址:Go 能够自动取变量的地址。在下面的代码中:

func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X+v.Y*v.Y) }
func main() {
    v := Vertex{3, 4}
    v.Abs()
}
登录后复制

表达式 v.Abs() 相当于代码:

vp := &v
vp.Abs()
登录后复制

在这种情况下,编译器会自动获取 v 变量的地址并将其传递给指针接收器方法 func (v *Vertex) Abs().

因此,在您提到的代码修改的情况下,无论无论您将值还是指针传递给 Abs() 方法,Go 的指针语义都会确保正确的行为。然而,在处理 Go 中的结构体等引用类型时,使用指针通常被认为是良好的做法。

以上是Go 指针:为什么我似乎可以向我的方法传递值或指针?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板