英文:
Why does embedding an Interface in a struct cause the Interface methodset to be defined as nil pointer?
问题
我正在学习Go语言,并遇到了在Go中将接口嵌入结构体的问题。
我理解接口及其实现的好处,但我对于将接口嵌入结构体的执行原因感到困惑。
当我在结构体中嵌入一个接口时,该结构体获得了该接口的方法集,并且现在可以作为接口类型变量的值使用,例如:
type Foo interface {
SetBaz(baz)
GetBaz() baz
}
type Bar struct {
Foo
}
现在我们有了一个嵌入了Foo
的结构体类型Bar
。因为Bar
嵌入了Foo
,所以Bar
现在满足任何需要类型为Foo
的接收器或参数,即使Bar
并没有明确定义它们。
尝试调用Bar.GetBaz()
会导致运行时错误:panic: runtime error: invalid memory address or nil pointer dereference
。
为什么Go会在嵌入接口的结构体上定义空方法,而不是通过编译器明确要求定义这些方法呢?
英文:
I'm working through learning Go, and I've come across embedding Interfaces into structs in Go.
I understand the joys of Interfaces and their implementations, but I'm confused as the reasoning for the current execution of embedding one inside a struct.
When I embed an interface in a struct, the struct gains the methodset of the Interface and can now be used as a value of an Interface type variable, eg:
type Foo interface {
SetBaz(baz)
GetBaz() baz
}
type Bar struct {
Foo
}
So now we have a struct type Bar
which embeds Foo
. Because Bar
embeds Foo
, Bar
now satisfies any receivers or arguments that require type Foo
, even though Bar
hasn't even defined them.
Trying to call Bar.GetBaz()
causes the runtime error: panic: runtime error: invalid memory address or nil pointer dereference
.
Why does Go define nil methods on a struct that embeds an interface instead of explicitly requiring those methods to be defined through the compiler?
答案1
得分: 7
你对于nil
方法的理解是错误的,实际上是嵌入到struct Bar
中的interface
是nil
。
当你使用接口的方法时,实际上调用的是这个接口。这个技巧允许我们覆盖接口方法。
要理解将interface
嵌入到struct
中的用法和目的,最好的例子是在sort
包中:
type reverse struct {
// 这个嵌入的接口允许 Reverse 使用另一个接口实现的方法。
Interface
}
// Less 返回嵌入实现的 Less 方法的相反结果。
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
// Reverse 返回数据的逆序。
func Reverse(data Interface) Interface {
return &reverse{data}
}
英文:
You're wrong about the nil
method, it's the interface
embedded into the struct Bar
that is nil
.
When you use the methods of the interface, that is this interface that is called. The trick allow you to override an interface method with our own.
To understand the usage and goals of embedding interfaces
into struct
, the best example is in the sort
package:
type reverse struct {
// This embedded Interface permits Reverse to use the methods of
// another Interface implementation.
Interface
}
// Less returns the opposite of the embedded implementation's Less method.
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
// Reverse returns the reverse order for data.
func Reverse(data Interface) Interface {
return &reverse{data}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论