【发布时间】:2020-12-09 09:49:25
【问题描述】:
我正在经历围棋之旅。我了解到,如果我们有一个接受指针作为接收者的方法,它也会接受一个值类型作为接收者(go 会自动进行转换)。
type Vertex struct { X, Y float64 }
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
那么下面的代码是有效的,无论是通过值还是指针接收Vertex
v := Vertex{1, 2}
fmt.Println(v.Abs())
p := &v
fmt.Println(p.Abs())
但是,假设我们有以下界面:
type Abser interface {
Abs() float64
}
那么,为什么下面的代码无效呢?
var a Abser
v := Vertex{1, 2}
a = v // invalid
我的理解是这样就可以了。即使 v 是一个值类型,它“实现”了接受指针接收器的 Abs 函数,它也会按值接受它?
接口是否只是为了更严格地定义接口变量在右侧可以保存的内容而设计的?该接口将 *Vertex 和 Vertex 视为两种不同的类型,但是 Abs() 方法也没有问题处理。
【问题讨论】:
-
The Tour of Go 是学习语言的资源,但如果你想出一些你认为奇怪的东西:阅读语言规范!规范golang.org/ref/spec非常短(比典型语言规范短一个数量级)并且令人惊讶地易于理解。它解释了诸如“可分配性”(即在什么条件下
x = y有效或无效)、“方法集”如何计算以及在这种情况下 Go 将自动取消引用或自动获取地址等相关概念。阅读它。