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

未初始化的嵌入式结构

未初始化的嵌入式结构

Go
青春有我 2022-07-04 16:56:49
我对这个 go 代码有点困惑。我有一个带有嵌入式结构(内部)的结构(外部),但是当我初始化外部时,我故意让嵌入式结构未初始化。type Inner struct {    value int}func (i *Inner) MyFunc() string {    return "inner"}func (i *Inner) OnlyInner() string {    return "only inner stuff"}type Outer struct {    *Inner}func (o *Outer) MyFunc() string {    return "outer"}func main() {    // embedded struct is *not* initialized    o := &Outer{}    fmt.Println(o.Inner)    fmt.Println(o.Inner.MyFunc())    fmt.Println(o.Inner.OnlyInner())    //fmt.Println(o.Inner.value)}输出:<nil>inneronly inner stuff如果我取消注释最后一行(用o.Inner.value),我会得到一个 nil 指针取消引用错误。这是怎么回事?有效的转到页面说(https://golang.org/doc/effective_go.html#embedding):当我们嵌入一个类型时,该类型的方法成为外部类型的方法,但是当它们被调用时,方法的接收者是内部类型,而不是外部类型。就我而言,内部类型似乎是<nil>,但方法调用执行没有问题。引擎盖下发生了什么?
查看完整描述

2 回答

?
莫回无

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

nil只要您不取消引用接收器本身,就可以使用接收器调用方法。


这意味着以下作品游乐场:


package main


import (

    "fmt"

)


type foo struct {

    val int

}


func (f *foo) Print() {

    fmt.Println("Receiver:", f)

}


func (f *foo) PrintVal() {

    fmt.Println("Val: ", f.val)

}


func main() {

    var f *foo

    f.Print()

    //f.PrintVal()

}

f.Print()工作没有问题,因为我们只是打印一个指针,我们不想取消引用它。


但是,f.PrintVal尝试取消引用nil指针,导致恐慌。


如有疑问,请记住此示例中的方法等效于将接收器作为第一个参数的函数:


func Print(f *foo)

func PrintVal(f *foo)

这在方法声明下的规范中提到:


方法的类型是以接收者为第一个参数的函数的类型。例如,方法 Scale 具有类型


func(p *Point, factor float64)


但是,以这种方式声明的函数不是方法。


这清楚地表明接收器没有什么特别的,nil只要你不取消引用它就可以。


查看完整回答
反对 回复 2022-07-04
?
智慧大石

TA贡献1946条经验 获得超3个赞

使用 nil-receiver 调用未初始化结构的方法。如果在使用该接收器的方法中,您会感到恐慌。使用 nil 接收器调用方法是有效的,并且该方法可以通过检查接收器是否为 nil 来修改其行为。



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

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号