我正在尝试识别一个使用switch实现接口的类型
package main
import "fmt"
type Abser interface {
Abs() float64
}
type Vertex struct {
X, Y int
}
func (v *Vertex) Abs() float64 {
return float64(v.X)
}
func do(i interface{}) {
switch v := i.(type) {
case Abser:
fmt.Println("theres an Abser")
case Vertex:
fmt.Println("theres a Vertex")
default:
fmt.Printf("I don't know about type %T!\n", v)
}
}
func main() {
do(Vertex{1,2})
}此代码输出Vertex而不是Abser的值。理想情况下,它应该有输出theres an Abser,因为顶点实现了Abs()方法。可以用一个开关箱来做这个吗?
发布于 2018-06-20 04:56:53
它不是关于开关命令,而是关于指针接收器。
如果您将func (v *Vertex) Abs() float64更改为func (v Vertex) Abs() float64,它将给出输出theres an Abser。
在一般的代码中,类型可以使用它的指针方法--您可以调用Vertex{1,2}.Abs(),但是后面发生的事情是Go编译器为您重写它为(&Vertex{1,2}).Abs()。因此,Vertex不实现Abser。
相反,指针类型拥有其基础类型所拥有的所有方法。因此,即使API被定义为func (v Vertex) Abs() float64,&Vertex{1,2}仍然是一个Abser。请参阅:https://play.golang.org/p/ONnsjApMywO
另请参阅:
方法集:sets
发布于 2018-06-20 04:46:50
问题是,顶点不是Abser,只有*顶点,如果您将Abs()修改为
func (v Vertex) Abs() float64 {
return float64(v.X)
}然后顶点本身就是一个Abser,您的代码将打印theres an Abser
https://stackoverflow.com/questions/50940348
复制相似问题