Go什么情況nil != nil

上述代碼執(zhí)行結(jié)果竟然是:

interface 變量定義是一個(gè) 16 個(gè)字節(jié)的結(jié)構(gòu)體,首 8 字節(jié)是類型字段,后 8 字節(jié)是數(shù)據(jù)指針。普通的 interface 是 iface 結(jié)構(gòu),interface{} 對(duì)應(yīng)的是 eface 結(jié)構(gòu);
interface 變量新創(chuàng)建的時(shí)候是 nil ,則這 16 個(gè)字節(jié)是全 0 值;
interface 變量的 nil 判斷,匯編邏輯是判斷首 8 字節(jié)是否是 0 值;
非空接口interface具體類型:
type iface struct {
? ? tab *itab // 接口本身信息接口方法,并且存儲(chǔ)具體類型所實(shí)現(xiàn)的信息
? ? data unsafe.Pointer // 內(nèi)存地址
}
空接口具體類型:
type eface struct {
? ? _type *_type // 具體類型信息
? ? data unsafe.Pointer // 內(nèi)存地址
}
type itab struct {
???? inter *interfacetype // 包含接口類型typ,包名,方法切面的結(jié)構(gòu)體指針
???? _type *_type // 下面說
????// 當(dāng)前類型的哈希值,runtime基于這個(gè)值構(gòu)建類型映射表,加速類型比較和查找
???? hash? uint32 // copy of _type.hash. Used for type switches.
???? _? ? ?[4]byte // 4字節(jié)用于內(nèi)存對(duì)齊
???? fun? ?[1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.? // 接口方法中的一個(gè)存儲(chǔ)在這里,如果fun[0]是0的話默認(rèn)不是某個(gè)結(jié)構(gòu)體的接口
}
type _type struct {
???? size? ? ? ?uintptr // 表示此類型的數(shù)據(jù)需要占用多少字節(jié)的存儲(chǔ)空間
???? ptrdata? ? uintptr // size of memory prefix holding all pointers ptrdata 表示數(shù)據(jù)的前多少字節(jié)包含指針,用來在應(yīng)用寫屏障時(shí)優(yōu)化范圍大小
???? hash? ? ? ?uint32 // 當(dāng)前類型的哈希值,runtime基于這個(gè)值構(gòu)建類型映射表,加速類型比較和查找
???? tflag? ? ? tflag // 額外的類型標(biāo)識(shí),目前由4個(gè)獨(dú)立的二進(jìn)制位組合而成。
???? align? ? ? uint8 // 表示當(dāng)前類型變量的對(duì)齊邊界
???? fieldAlign uint8 // 表示當(dāng)前類型的 struct 字段的對(duì)齊邊界
???? kind? ? ? ?uint8 // 表示當(dāng)前類型所屬的分類,目前 Go語言的 reflect 包中定義了 40 種有效分類
???? equal func(unsafe.Pointer, unsafe.Pointer) bool // 用來比較兩個(gè)當(dāng)前類型的變量是否相等
???? gcdata? ? *byte // 和垃圾回收相關(guān),GC 掃描和寫屏障用來追蹤指針
???? str? ? ? ?nameOff // 偏移,通過 str 可以找到當(dāng)前類型的名稱等文本信息
???? ptrToThis typeOff // 偏移,假設(shè)當(dāng)前類型為 T,通過它可以找到類型 * T的類型元數(shù)據(jù)
}
type interfacetype struct {
???? typ? ? ?_type // 接口類型typ
???? pkgpath name // 包路徑名pkgpath
???? mhdr? ? []imethod // 存儲(chǔ)接口方法集的切片mhdr
}
我們進(jìn)行空接口和非空接口類型變量賦值的時(shí)候,返回如果是nil的接口體指針,就會(huì)導(dǎo)致,*itab 或者 *_type不是nil,是有類型指針的,這塊大家需要注意!