我试图理解界面如何在Go中运作。
我们说我有2个结构:
package "Shape"
type Square struct {
edgesCount int
}
type Triangle struct {
edgesCount int
}
现在我创建一个Shape
界面:
type Shape interface {
}
为什么我不能指定Shape
接口具有egdesCount
属性?接口是否应该重新组合方法?
我面临的另一个问题是共享功能。不可能想出这样的东西:
func New() *Shape {
s:=new(Shape)
s.edgesCount = 0
return s
}
这比重写完全相同的代码要好得多:
func New() *Square {
s:=new(Square)
s.edgesCount = 0
return s
}
func New() *Triangle {
s:=new(Triangle)
s.edgesCount = 0
return s
}
(这也带来了问题,因为我无法重新声明我的New
功能......)
非常感谢你的帮助
答案 0 :(得分:3)
您所指的不是接口(允许将对象作为该接口传递,只是因为该对象是所有接口方法的接收器)。
这里是empty interface{}' Shape
would be satisfied by any type,在这里没用。
更多关于type embedding(例如使用anonymous type structure):
这将提升两个结构域的公共字段edgesCount
正如spec mentions:
f
中匿名字段的字段或方法struct x
称为已提升,如果x.f
是表示该字段或方法的合法选择器{ {1}}。
请参阅this example:
f
输出:
type Shape struct {
edgesCount int
}
type Square struct {
Shape
}
type Triangle struct {
Shape
}
func NewSquare() *Square {
return &Square{
Shape{edgesCount: 4},
}
}
func NewTriangle() *Triangle {
return &Triangle{
Shape{edgesCount: 3},
}
}
func main() {
fmt.Printf("Square %+v\n", NewSquare())
fmt.Printf("Triangle %+v\n", NewTriangle())
}
答案 1 :(得分:2)
Go不是面向对象的语言,这些字段是内部字段,因为它们以小写字母开头。相反,尝试这样的事情:
type Shape interface {
EdgeCount() int
}
type Square struct {
edgesCount int
}
func (s Square) EdgeCount() int {
return s.edgesCount
}
type Triangle struct {
edgesCount int
}
func (t Triangle) EdgeCount() int {
return t.edgesCount
}
现在,您可以在任一类型的对象上使用EdgeCount函数,因为它们都实现了Shape接口。
func IsItSquare(s Shape) bool {
// If it has 4 sides, maybe
return s.EdgeCount == 4
}
但是你仍然需要使用独立的New函数创建不同类型的形状,或者只是通过字面声明它们。
// Obviously a contrived example
s := Triangle{edgesCount: 3}
答案 2 :(得分:0)
仅接口组方法,因为它们的目的是定义行为,非常类似于其他语言(例如,请参阅Java Interfaces)。
您正在寻找的是类似代码继承的东西,它在Go中并不存在。但是,您可以使用struct embedding获得类似的内容:
Go没有提供典型的,类型驱动的子类化概念,但它确实能够通过在结构或接口中嵌入类型来“借用”实现的各个部分。
因此,您可以通过执行以下操作获得所需内容(play link):
type Shape struct {
edgeCount int
}
func (s Shape) EdgeCount() int {
return s.edgeCount
}
type Square struct {
Shape
}
type Triangle struct {
Shape
}
func main() {
sq := Square{Shape{edgeCount: 4}}
tr := Square{Shape{edgeCount: 3}}
fmt.Println(sq.EdgeCount())
fmt.Println(tr.EdgeCount())
}