取自巡演:
package main
import (
"fmt"
"math"
)
type Abser interface {
Abs() float64
}
func main() {
var a Abser
f := MyFloat(-math.Sqrt2)
v := Vertex{3, 4}
a = f
a = &v
// v == Vertex != *Vertex -> exception
a = v
}
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
但是,将func (v *Vertex) Abs() float64
转换为func (v Vertex) Abs() float64
时,代码会编译:
package main
import (
"math"
)
type Abser interface {
Abs() float64
}
func main() {
var a Abser
f := MyFloat(-math.Sqrt2)
v := Vertex{3, 4}
a = f
// Since *Vertex != Vertex, this shouldn't compile, should it?
a = &v
a = v
}
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
为什么第二个例子会运行?
答案 0 :(得分:4)
类型*T
不是T
的子类,但*T
的{{3}}将继承T
的方法:
任何其他类型T的方法集由用接收器类型T声明的所有方法组成。相应指针类型* T的方法集是用receiver * T或T声明的所有方法的集合(也就是说,它也是包含T)的方法集。
因此,如果T
符合特定接口,那么*T
也是如此。这就是为什么您可以为示例中的*Vertex
变量指定Abser
值。