取自 go tour:
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)
}
为什么第二个例子运行?
最佳答案
类型*T
不是T
的子类,而是*T
的method set将继承T
的方法:
The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T).
因此,如果 T
符合特定接口(interface),那么 *T
也符合。这就是为什么您可以将 *Vertex
值分配给示例中的 Abser
变量。
关于Go: *Var 是 Var 的 "subclass"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26497002/