2012-06-13 65 views
5

當我偶然發現這種明顯的不一致時,我正在做一個簡單的鏈接列表界面來了解Go界面。 nextT始終爲零,但next()的返回值不是。指針接收器不一致(Go bug?)

package main 

import (
    "fmt" 
) 

type LinkedList interface { 
    next() LinkedList 
} 

type T struct { 
    nextT *T 
} 

func (t *T) next() LinkedList { 
    //uncomment to see the difference 
    /*if t.nextT == nil { 
     return nil 
    }*/ 
    return t.nextT//this is nil! 
} 

func main() { 
    t := new(T) 
    fmt.Println(t.nextT == nil) 

    var ll LinkedList 
    ll = t 
    fmt.Println(ll.next() == nil)//why isn't this nil? 
} 
next()

沒有零檢查(我不應該這樣做),我得到

true 
false 

有了它,我得到預期的結果

true 
true 

有我發現了一個錯誤還是出於某種原因,這是意外的驚喜?使用zip安裝(無MSI)在Go版本1上運行

回答

7

不,這不是一個錯誤。 Go中的一個接口基本上是一對兩個值:一個類型信息和一個指向實際數據的指針。將無類型值nil分配給接口(接口也恰好是接口的零值)意味着該接口既沒有類型信息也沒有指向存儲的任何數據的指針。另一方面,將*T指針分配給接口,將相應地設置類型信息並讓數據指針指向該指針。在這種情況下,界面不再是nil,因爲您已經存儲了一個具有特定值的特定類型。在你的情況下,恰好你所存儲的值是零。您可以使用類型斷言(或reflect包)來檢查接口是否具有指定的特定類型。類型斷言只有在類型信息匹配的情況下才會成功(如果之前您已將nil指定給該接口,則顯然不會是這種情況)。如果測試成功,您將返回*T,但此指針可能仍具有值nil(這是該類型的有效值)。

查看Go標準庫中的container/list軟件包以查看更常用的常規鏈表實現。還有Russ Cox的excellent article,其中包含Go的界面類型的深入解釋。