我是戈朗的新手。我從 go 之旅開始。這是go playground 鏈接這是代碼:package mainimport "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它不再恐慌在這兩種情況下,行為不應該相似嗎?如果不是,為什么?
2 回答

ABOUTYOU
TA貢獻1812條經驗 獲得超5個贊
您正在聲明但未明確定義t
在兩種情況下都命名的變量。如果不指定值,則分配變量類型的零值
所有指針類型的零值,包括*T
nil。結構類型的零值是該結構的所有字段都設置為零值的值。
當為變量 [...] 分配存儲并且未提供顯式初始化時,變量或值將被賦予默認值。此類變量或值的每個元素都設置為其類型的零值:布爾值為 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()被稱為。
- 2 回答
- 0 關注
- 130 瀏覽
添加回答
舉報
0/150
提交
取消