理解 Go 中的接口
Understanding interfaces in Go
我正在尝试了解接口在 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
函数...)
非常感谢您的帮助
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}
您所指的不是接口(它允许将对象作为该接口传递,仅仅是因为该对象是所有接口方法的接收者)。
在这里,一个empty interface{}' Shape
would be satisfied by any type,在这里没有用。
例如type embedding (using an ):
这将提升公共字段edgesCount
到两个结构。
作为 spec mentions:
A field or method f
of an anonymous field in a struct x
is called promoted if x.f
is a legal selector that denotes that field or method 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}}
仅接口组方法,因为它们的目的是定义行为,与其他语言非常相似(例如,参见 Java Interfaces)。
您正在寻找的是代码继承之类的东西,Go 中不存在。但是,你可以用 struct embedding:
得到类似的东西
Go does not provide the typical, type-driven notion of subclassing, but it does have the ability to “borrow” pieces of an implementation by embedding types within a struct or interface.
因此,您可以通过执行以下操作 (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())
}
我正在尝试了解接口在 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
函数...)
非常感谢您的帮助
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}
您所指的不是接口(它允许将对象作为该接口传递,仅仅是因为该对象是所有接口方法的接收者)。
在这里,一个empty interface{}' Shape
would be satisfied by any type,在这里没有用。
例如type embedding (using an
这将提升公共字段edgesCount
到两个结构。
作为 spec mentions:
A field or method
f
of an anonymous field in astruct x
is called promoted ifx.f
is a legal selector that denotes that field or methodf
.
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}}
仅接口组方法,因为它们的目的是定义行为,与其他语言非常相似(例如,参见 Java Interfaces)。
您正在寻找的是代码继承之类的东西,Go 中不存在。但是,你可以用 struct embedding:
得到类似的东西Go does not provide the typical, type-driven notion of subclassing, but it does have the ability to “borrow” pieces of an implementation by embedding types within a struct or interface.
因此,您可以通过执行以下操作 (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())
}