为什么用指针分配接口然后分配地址在 Golang 中显示不同的行为

我是戈朗的新手。我从 go 之旅开始。这是go playground 链接

这是代码:


package main


import "fmt"


type I interface {

    M()

}


type T struct {

    S string

}


func (t *T) M() {


    fmt.Println(t.S)

}


func main() {

    var i I


    var t *T 

    i = t


    i.M()

}

它很恐慌


恐慌:运行时错误:无效内存地址或零指针取消引用[信号 SIGSEGV:分段违规代码=0xffffffff 地址=0x0 pc=0xd3ea6] goroutine 1 [运行]:main.(*T).M(0x0, 0x434070) /tmp/ sandbox696069628/main.go:15 +0x26 main.main() /tmp/sandbox696069628/main.go:24 +0x40


但是当我改变


var t *T 

i = t


var t T 

i = &t

它不再恐慌


在这两种情况下,行为不应该相似吗?如果不是,为什么?


蝴蝶不菲
浏览 106回答 2
2回答

ABOUTYOU

您正在声明但未明确定义t在两种情况下都命名的变量。如果不指定值,则分配变量类型的零值所有指针类型的零值,包括*Tnil。结构类型的零值是该结构的所有字段都设置为零值的值。当为变量 [...] 分配存储并且未提供显式初始化时,变量或值将被赋予默认值。此类变量或值的每个元素都设置为其类型的零值:布尔值为 false,数字类型为 0,字符串为 "",指针、函数、接口、切片、通道和映射为 nil。此初始化是递归完成的,因此,例如,如果未指定值,则结构数组的每个元素都将其字段清零。https://golang.org/ref/spec#The_zero_value因此,这会将 nil 存储在接口值中i:var i interface{ M() }var t *T i = t// i stores nil这在接口值中存储了一个结构值i:var i interface{ M() }var t T i = t// i stores T{S:""}所以在第一种情况下,(nil).M()被称为(恐慌),在第二种情况下(T{}).M()被称为。

哆啦的时光机

你没有初始化 T。这样做:var t *T = &T{"Hello World"}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go