我目前正在学习用围棋语言编程. 我在理解围棋指针时遇到了一些困难(我的C/C++现在已经很远了…). 例如,在52号围棋巡回赛(http://tour.golang.org/#52)中,我读到:

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) Abs() float64 {
[...]
v := &Vertex{3, 4}

我写道:

func (v Vertex) Abs() float64 {
[...]
v := Vertex{3, 4}

甚至:

func (v Vertex) Abs() float64 {
[...]
v := &Vertex{3, 4}

反之亦然:

func (v *Vertex) Abs() float64 {
[...]
v := Vertex{3, 4}

我得到了完全相同的结果.有区别吗(记忆方面的,等等)?

推荐答案

您的示例使用的围棋语言有两种不同的规则:

  1. 可以从具有值接收器的方法导出具有指针接收器的方法.因此,func (v Vertex) Abs() float64将自动生成一个额外的方法实现:

    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 := &Vertex{3, 4}
    v.Abs()  // calls the generated method
    
  2. 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()
    

Go相关问答推荐

Go 1.22 net/http群组路由

SEARCH On Conflict Clause不考虑乐观锁定版本

如何在AWS SDK Go v2 STS上正确使用重试

是不是有什么原因导致`Strings.EqualFold`不先进行长度比较?

从MySQL/GO表获取行数据

golang regex基于关键字拆分字符串

是否可以在 hyperledger-chaincode 中使用 gRPC?如果可以,我如何避免在测试网络上调用时出错?

如何使用 sync.WaitGroup 来执行所有的 goroutine?

Gorm 在自定义字符串类型上返回 scanner 错误

如何以干净的方式在中间件中注入 repo 或服务?

Gremlin-Go:树步骤不可序列化

在 .go 文件中运行一个函数和在 Go 模板中调用它有什么区别?

如何在 Golang http.Request 对象中读取自定义 ajaxParams

使用 Golang 在字符串中循环重复数据

在 go 中将运行命令的标准输出发送到其标准输入

将 Golang Gin 与 AWS Lambda 和无服务器与代理路径一起使用

什么是无效字符实体 &ccb

GOLANG 如何使用 http.FileServer 从模板目录加载某个 html 文件

Scanner.Buffer - 最大值对自定义拆分没有影响?

在 VSCode 中使用命令行参数调试 Go 测试