意料之外:空接口和nil的比較

當將一個值為nil的接口變量w賦值給空接口類型i后胧谈,i為nil。

// case 1
var i interface{}
var w io.Writer
i = w
print(i == nil) // true

但是將一個值為nil的接口指針變量w賦值給空接口類型i后荸频,i就不等于nil了菱肖。

// case 2
var i interface{}
var w *io.Writer
i = w
print(i == nil) // false

what???

當我無意間測試到這種case之后,缺失有點不知所以旭从。
下面我們就通過反射和debug查看到底發(fā)生了什么稳强。
有個常識需要再提一下:判斷一個空接口類型的變量是否為nil時,只有當type和value同時為nil時和悦,空接口類型變量才為nil退疫。
有個進階的知識需要提前說一下:空接口類型數(shù)據(jù)在類型系統(tǒng)中的表示對應的是runtime.eface,如下所示鸽素;在反射包中有對應結構褒繁,那就是:reflect.emptyInterface,結構如下:

type eface struct {
    _type *_type              // 類型信息           
    data  unsafe.Pointer  // 值信息
}

// emptyInterface is the header for an interface{} value.
type emptyInterface struct {
    typ  *rtype                  // 類型信息
    word unsafe.Pointer  // 值信息
}

先用goland debug一下(使用reflect.TypeOf方法測試i的類型信息)付鹿。

case 1的情況:


image.png

case 2的情況:


image.png

可以看到case1的type為nil澜汤,而case2的type不為nil,所以case 2的i不為nil舵匾。

下面通過調試工具delve來看一下結果:
case 1:


image.png

case 2:


image.png

和顯然和goland中調試結果是一致的俊抵。只不過我們在使用delve調試的時候,可以輸出空接口runtime的表示坐梯,而goland ide只能通過調用反射功能窺視類型數(shù)據(jù)徽诲。
另外,我們注意到case 2中kind=54吵血,和我們見到的reflect.Kind枚舉數(shù)據(jù)對不上谎替。則是因為kind: 54需要和kindMask = (1 << 5) - 1,做一次與運算就和reflect.Kind對應了蹋辅,與運算后是22钱贯,就是reflect.Ptr的值。

func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }

// A Kind represents the specific kind of type that a Type represents.
// The zero Kind is not a valid kind.
type Kind uint

const (
    Invalid Kind = iota
    Bool
    Int
    Int8
    Int16
    Int32
    Int64
    Uint
    Uint8
    Uint16
    Uint32
    Uint64
    Uintptr
    Float32
    Float64
    Complex64
    Complex128
    Array
    Chan
    Func
    Interface
    Map
    Ptr
    Slice
    String
    Struct
    UnsafePointer
)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末侦另,一起剝皮案震驚了整個濱河市秩命,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌褒傅,老刑警劉巖弃锐,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異殿托,居然都是意外死亡霹菊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門支竹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旋廷,“玉大人鸠按,你說我怎么就攤上這事×螅” “怎么了待诅?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長熊镣。 經(jīng)常有香客問我,道長募书,這世上最難降的妖魔是什么绪囱? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮莹捡,結果婚禮上鬼吵,老公的妹妹穿的比我還像新娘。我一直安慰自己篮赢,他們只是感情好齿椅,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著启泣,像睡著了一般涣脚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寥茫,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天遣蚀,我揣著相機與錄音,去河邊找鬼纱耻。 笑死芭梯,一個胖子當著我的面吹牛,可吹牛的內容都是我干的弄喘。 我是一名探鬼主播玖喘,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蘑志!你這毒婦竟也來了累奈?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤卖漫,失蹤者是張志新(化名)和其女友劉穎费尽,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體羊始,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡旱幼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了突委。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柏卤。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡冬三,死狀恐怖,靈堂內的尸體忽然破棺而出缘缚,到底是詐尸還是另有隱情勾笆,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布桥滨,位于F島的核電站窝爪,受9級特大地震影響,放射性物質發(fā)生泄漏齐媒。R本人自食惡果不足惜蒲每,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喻括。 院中可真熱鬧邀杏,春花似錦、人聲如沸唬血。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拷恨。三九已至脖律,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挑随,已是汗流浹背状您。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留兜挨,地道東北人膏孟。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像拌汇,于是被迫代替她去往敵國和親柒桑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內容