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

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

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

Go
交互式爱情 2022-09-26 19:52:54
我发现很难理解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()为什么一个有效而另一个恐慌呢?
查看完整描述

2 回答

?
MYYA

TA贡献1868条经验 获得超4个赞

正如 Go 文档中提到的Method_declarations,方法绑定到接收器的基本类型。

接收器通过方法名称前面的额外参数部分指定。该参数部分必须声明一个非可变参数参数,即接收器。其类型必须是已定义类型 T 或指向已定义类型 T 的指针,T 称为接收方基类型。接收器基类型不能是指针或接口类型,并且必须在与方法相同的包中定义。该方法称为绑定到其接收器基类型,并且方法名称仅在类型 T 或 *T 的选择器中可见。

所以你的方法绑定到*main。一种类型和类型也 *主要.因此,允许调用方法。但是,如果您在方法内部用作值,它也会崩溃。var aWalk()a

在你的类型中,的默认类型是nil,这就是为什么它很恐慌。您必须将接口实现类型注入以避免恐慌。bBTestInterfaceB

func 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.

}

操场上奔跑


查看完整回答
反对 回复 2022-09-26
?
芜湖不芜

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

由于上面的@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() 

}```


查看完整回答
反对 回复 2022-09-26
  • 2 回答
  • 0 关注
  • 82 浏览
慕课专栏
更多

添加回答

举报

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