为了账号安全,请及时绑定邮箱和手机立即绑定

理解 Go 中的接口

理解 Go 中的接口

Go
至尊宝的传说 2021-09-13 10:23:27
我试图了解接口在 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功能......)非常感谢您的帮助
查看完整描述

3 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

您所指的不是接口(它允许将对象作为该接口传递,仅仅是因为该对象是所有接口方法的接收器)。

在这里,任何类型都可以满足空值interface{}' Shape,这在这里没有用。


更多关于类型嵌入(例如使用匿名类型结构):


这将促进共同项目edgesCount这两个结构。

正如规范所提到的:


字段或方法f在一个匿名字段的struct x被称为促进如果x.f是一个合法的选择器,它表示字段或方法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())

}

输出:


Square &{Shape:{edgesCount:4}}

Triangle &{Shape:{edgesCount:3}}


查看完整回答
反对 回复 2021-09-13
?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

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}


查看完整回答
反对 回复 2021-09-13
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

接口仅对方法进行分组,因为它们的目的是定义行为,非常类似于其他语言(例如,请参阅Java 接口)。


您正在寻找的是类似于代码继承的东西,它在 Go 中不存在。但是,您可以通过struct embedding获得类似的东西:


Go 没有提供典型的、类型驱动的子类化概念,但它确实有能力通过在结构或接口中嵌入类型来“借用”实现的片段。


因此,您可以通过执行以下操作(播放链接)来获得您想要的内容:


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())

}


查看完整回答
反对 回复 2021-09-13
  • 3 回答
  • 0 关注
  • 187 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信