我正在尝试使用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
,因为Vertex实现了Abs()
方法。是否可以使用开关盒来做到这一点?
答案 0 :(得分:2)
这与切换命令无关,而与指针接收器有关。
如果将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
另请参见:
答案 1 :(得分:0)
问题在于,如果您将Abs()的impl更改为
,则Vertex不是Abser,只有* Vertex是。func (v Vertex) Abs() float64 {
return float64(v.X)
}
然后,顶点本身就是Abser,您的代码将显示theres an Abser