3 回答

TA貢獻1825條經驗 獲得超4個贊
接口值是一個簡單的數據結構,由兩部分組成:類型和基礎值。因此,接口值本身可以是 ,或者接口值可以存在,但基礎值可以是 。例如:nilnil
var x interface{} = nil // x is nil
var y interface{} = (interface{})(nil) // y is a interface{}, which *contains* nil
這在某些概念上與此差異相似:
var x []*int = nil // x is nil
var y []*int = []*int{nil} // y is a []*int, which *contains* nil
fmt.Printf由于接口格式化輸出的方式,掩蓋了接口情況下的差異;如果您愿意,可以使用反射更清楚地看到差異。

TA貢獻1873條經驗 獲得超9個贊
在 Go 中,引用某些接口的實現者的變量可以具有多種類型。它可以是類型(是的,可以描述類型以及值),它可以是其實現者之一的類型,也可以是指向其實現者之一的指針的類型。默認情況下,引用接口的變量的類型為 。一旦你向它分配了一些東西(除了它本身),它就會采用你分配給它的東西的類型(同樣,要么是它的實現者之一的類型,要么是指向其中一種類型的指針)。<nil>nilnilnil
可以使用 打印接口變量的類型,并使用 %v 打印其值:%T
func main() {
var i SomeInterface
fmt.Printf("%T, %v\n", i, i) // Prints <nil>, <nil>
var someStruct SomeStruct
i = someStruct
fmt.Printf("%T, %v\n", i, i) // Prints main.SomeStruct, {}
var someStructPtr *SomeStruct
i = someStructPtr
fmt.Printf("%T, %v\n", i, i) // Prints *main.SomeStruct, <nil>
}
現在,每當您比較時,只有當兩個操作數的類型和值都匹配時,比較才會被計算為 true。在你的情況下,的值顯然是(畢竟,的值肯定是 ,并且你將其值存儲在 中)。的類型,根據我剛才解釋的內容,必須是 。的價值顯然是。h.SomeObject == nilh.SomeObject<nil>someStruct<nil>h.SomeObjecth.SomeObject*SomeStructnil<nil>
但是,是什么類型?nil
好吧,可以采用多種類型,編譯器必須決定每種用法應該采用哪種類型。當涉及到比較和分配時,它只是簡單地采用它被比較或分配的東西的類型。例如,如果要將整數指針與 進行比較,則在這種情況下,類型為 。nilnilnil*int
但所有這些都必須在編譯時決定,并且引用接口的變量可以在運行時更改類型。那么,當您將引用接口的變量與 進行比較時,在這種情況下,編譯器會為操作數提供什么類型呢?好吧,它給了它唯一合理的類型, .nilnil<nil>
最后一個示例,請考慮以下代碼:
func main() {
var p *SomeStruct = nil // = nil is optional; pointers default to nil
var i SomeInterface = p
printf("%t\n", p == nil) // Prints true
printf("%t\n", p == i) // Prints true
printf("%t\n", i == nil) // Prints false
}
p == nil為 true,因為 is 的類型帶有值 ,并且(在本例中)也是具有值的類型。p*SomeStruct<nil>nil*SomeStruct<nil>
p == i是 true,因為 也是具有值的類型(它只是存儲 的類型和值)。i*SomeStruct<nil>p
但是,是 false,因為在這種情況下,采用的類型而不是 。i == nilnil<nil>*SomeStruct
解決這個問題的方法是永遠不要在接口引用變量中存儲一些有價值的東西,除了它本身。這樣,每當接口引用變量的值為 時,其類型也將是 ,并且比較將按預期工作。因此,您經常會看到如下所示的代碼:<nil>nil<nil><nil>nil
if p == nil {
i = nil
} else {
i = p
}

TA貢獻1847條經驗 獲得超7個贊
SomeObject 不是 nil,它只是指向 SomeStruct,它是 nil。
我認為混亂是fmt。Printf打印這種情況,因為它遵循指針,最終結果是零。<nil>
- 3 回答
- 0 關注
- 147 瀏覽
添加回答
舉報