Go 在;“一次旅行”;,如何修改接口,使其需要指针上的方法?
在中,我们有这个接口:Go 在;“一次旅行”;,如何修改接口,使其需要指针上的方法?,go,Go,在中,我们有这个接口: type Abser interface { Abs() float64 } 据解释,该类型顶点不满足上述Abser: type Vertex struct { X, Y float64 } func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } 如何修改Abser接口以使顶点满足它 (在完整示例中,如果它不再满足MyFloat,那也没关系。) 在我发布这个
type Abser interface {
Abs() float64
}
据解释,该类型顶点不满足上述Abser:
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
如何修改Abser接口以使顶点满足它
(在完整示例中,如果它不再满足MyFloat,那也没关系。)
在我发布这个问题之前,我花了几个小时搜索和挠头,但在发布之后,我发现了另一个SO问题,涵盖了类似的材料,可能对其他新手有所帮助:
您对什么是实现什么有点困惑。在这种情况下,
*Vertex
正在实现Abser
,而不是Vertex
,要使其成为Vertex
也可以,您必须更改Abs
实现的接收类型,使其不是指针
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
} // Vertex implementing Abser here
所以你的措辞有点误导。接口不需要更改,也不应收到任何更改。仅供参考,您可以让*Vertex
和Vertex
使用我上面介绍的方法以及您已有的方法来实现该接口
这一点在围棋中经常会让人绊倒。当您声明func(t SomeType)
时,您正在指定接收类型,如果这是一个类似(t*SomeType)
的指针,那么实现接口的不是SomeType
,而是*SomeType
。这与其他语言略有不同,在其他语言中,方法是由类实现的,不管您使用的是引用还是值。在Go中,类不实现方法,您指定“接收类型”-方法可以调用的对象-第一个参数实际上被推送到堆栈上,并与传递到方法中的参数相同,区别仅与编译相关(接口实现实际上是拥有afaik功能的唯一原因)。因此,总结一下,如果您希望Vertex
实现Abser
接口,该接口具有单个方法Abs()float64
,那么您需要将函数定义为func(v Vertex)Abs()float64{…}
为了使代码清晰易读,我建议不要同时为指针和值定义接口……您可以使用address of或dereference操作符解决这个问题。您不能,因为
type Vertex
根本没有任何方法(只有*Vertex
有方法).谢谢你的详细回答,尽管“有点困惑”有点轻描淡写;我现在感觉特别难受。@DavidSmith我怎样才能帮助消除这种混淆呢?这样想,实现类型就是函数名左边括号中的类型。AnyType
和*AnyType
不是同一类型。无论使用哪种类型,都会影响如果你不熟悉这些接口的区别,我建议你读一下关于指针和值vs引用类型的一些东西。大多数概念在许多系统语言中都是相关的(C,C++,C,等等)。.你很有耐心-我知道如何更改Abs以匹配接口,但我想到的问题是,如何做相反的操作;更改接口以使当前顶点满足它。我想我没有任何使用接口的经验,因此从阅读你的答案来看,这可能只是一个胡说八道;你永远不会定义接口需要类型才能具有只作用于指针的函数的接口?@DavidSmith最后一个问题,是的。您所指的是不可能的,也没有多大意义。在Go中,指针的类型与值版本明显不同。如果您想这样做,则实现接口所需的只是一个函数指针,你可能想使用嵌入。如果你想要的话,我可以详细说明。但是为了提供更多的上下文,这基本上就像在C中的结构上有一个函数指针。对于实现接口的类型,它必须匹配函数定义,因为接口不能由函数指针组成。