在"A Go Tour" on Interfaces中我们有这个界面:
type Abser interface {
Abs() float64
}
据说这种类型Vertex不满足上述Abser:
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
如何修改Abser界面以使Vertex满足它?
(如果在完整的例子中它不再满足MyFloat就没关系。)
在我发布这个问题之前,我花了几个小时搜索并抓挠,但在发布后我发现了另一个SO问题,涵盖了类似的材料,可能对其他新手有所帮助:
"method requires pointer receiver” in Go Programming Language
答案 0 :(得分:2)
你对实施什么感到有些困惑。在这种情况下,*Vertex
正在实施Abser
而不是Vertex
以便Vertex
这样做,您必须更改{{1}的实施时的接收类型所以它不是指针;
Abs
所以你对这个问题的表达方式有点误导。界面不需要更改,也不应该收到任何更改。只需fyi,您可以让func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
} // Vertex implementing Abser here
和*Vertex
使用上面提到的方法以及您已有的方法实现接口。
这一点经常让人们在Go中绊倒。当您声明Vertex
指定接收类型时,如果这是一个像func (t SomeType)
这样的指针,那么实现该接口的东西不是(t *SomeType)
而是SomeType
。这与该类实现该方法的其他语言稍有不同,如果您使用的是引用或值,则无关紧要。在Go中,类没有实现该方法,你指定'接收类型' - 可以调用该方法的东西 - 第一个参数实际上被推送到堆栈并且使用相同的方法作为传递给方法的参数,区别仅与编译有关(界面实现确实是使该功能具有afaik的唯一原因)。总而言之,如果您希望*SomeType
实现具有单个方法Vertex
的{{1}}接口,则需要将该函数定义为Abser
。
只是为了拥有清晰可读的代码,我建议不要为指针和值定义接口......你可以使用地址或解除引用运算符解决这个问题。