结构中的嵌入式接口以非常奇怪的方式运行

我发现很难理解Go在内部是如何工作的。在某些情况下,它表现出奇怪的行为。


type TestInterface interface {

   Walk()

}


type A struct {

}


func (a *A) Walk() {

   fmt.Println("hello world")

}


type B struct {

   TestInterface

}


func main() {

    var a *A

    b := B{}


    a.Walk() // This will not panic even though a is nil

    b.Walk() // This will panic.

}

由于 嵌入 ,将以与调用类似的方式在结构上内部调用方法。bTestInterfaceb.Walk()WalkAa.Walk()


为什么一个有效而另一个恐慌呢?


交互式爱情
浏览 83回答 2
2回答

MYYA

正如 Go 文档中提到的Method_declarations,方法绑定到接收器的基本类型。接收器通过方法名称前面的额外参数部分指定。该参数部分必须声明一个非可变参数参数,即接收器。其类型必须是已定义类型 T 或指向已定义类型 T 的指针,T 称为接收方基类型。接收器基类型不能是指针或接口类型,并且必须在与方法相同的包中定义。该方法称为绑定到其接收器基类型,并且方法名称仅在类型 T 或 *T 的选择器中可见。所以你的方法绑定到*main。一种类型和类型也 *主要.因此,允许调用方法。但是,如果您在方法内部用作值,它也会崩溃。var aWalk()a在你的类型中,的默认类型是nil,这就是为什么它很恐慌。您必须将接口实现类型注入以避免恐慌。bBTestInterfaceBfunc main() {    var a *A    b := B{TestInterface:a}    fmt.Println(reflect.TypeOf(a), b)    a.Walk() // This will not panic even though a is nil    b.Walk() // This will not panic anymore.}在操场上奔跑

芜湖不芜

由于上面的@mkopriva评论,我以下列方式修改了程序,现在有意义了。这也意味着 Go 中的 nil 具有与之关联的类型。type TestInterface interface {   Walk()}type A struct {}func (a *A) Walk() {   fmt.Println("hello world")}type B struct {   TestInterface}func main() {    var a *A        b := B{TestInterface: a}        // both will not panic    a.Walk()     // TestInterface is still nil as a is nil.    b.Walk() }```
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go