golang 中的 nil的場景分析
源碼中的 nil 是這樣定義的
// nil is a predeclared identifier representing the zero value for a // pointer, channel, func, interface, map, or slice type. var nil Type // Type must be a pointer, channel, func, interface, map, or slice type
所以 nil 可以理解為這些類型的零值,聲明一個變量在沒有賦值的情況下,變量處于零值狀態(tài)。
場景一
func t1() { var i interface{} var p *int fmt.Println("p==i", p == i) fmt.Println("i=", i, "i==null", i == nil) fmt.Println("p=", p, "p==nil", p == nil) fmt.Println("i TypeOf=", reflect.TypeOf(i), "i ValueOf", reflect.ValueOf(i)) fmt.Println("p TypeOf=", reflect.TypeOf(p), "p ValueOf", reflect.ValueOf(p)) i = p fmt.Println("---") fmt.Println("p==i", p == i) fmt.Println("i=", i, "i==null", i == nil) fmt.Println("p=", p, "p==nil", p == nil) fmt.Println("i TypeOf=", reflect.TypeOf(i), "i ValueOf", reflect.ValueOf(i)) fmt.Println("p TypeOf=", reflect.TypeOf(p), "p ValueOf", reflect.ValueOf(p)) }
真相是 i 剛開始沒有類型,而 p 是有類型,所以 p 和 i 都等于 nil,但是 == 可以理解為 php 或者 js 里面的 === 全等,既要類型相等,也要值相等。
在 i = p 之后,p 和 i 類型和值保持了一致所以會相等,但是 i 已經(jīng)不等于 nil 了,因為 nil 是 interface 的 0 值,或者說 i 已經(jīng)指向 p ,i 現(xiàn)在是個有類型狀態(tài)而非 0 值狀態(tài)。
結(jié)果如下
p==i false
i= <nil> i==null true
p= <nil> p==nil true
i TypeOf= <nil> i ValueOf <invalid reflect.Value>
p TypeOf= *int p ValueOf <nil>
---
p==i true
i= <nil> i==null false
p= <nil> p==nil true
i TypeOf= *int i ValueOf <nil>
p TypeOf= *int p ValueOf <nil>
場景二
func t3() { f1 := func(i interface{}) bool { return i == nil } var a *int fmt.Println(f1(a)) // false fmt.Println(f1(nil)) // true }
a 傳遞到 func 里面,被轉(zhuǎn)成 interface,這個 interface 是有類型的 interface,相當(dāng)于賦值了一下 i=a ,所以 i 的狀態(tài)不是 interface 的零值狀態(tài) ,和 interface 零值狀態(tài)的 nil 當(dāng)然是不相等
場景三
type A struct { } func (A) a1() int { return 123 } func (*A) a2() int { return 321 } type B interface { } func t2() { var a A var ap *A var b B var bp *B fmt.Println("a=", a, "a.a1()", a.a1(), a.a2()) //a= {} a.a1() 123 321; a == nil 會拋錯 struct 不能和 nil 進行比較 fmt.Println("ap=", ap, "ap==nil", ap == nil) //ap= <nil> ap==nil true fmt.Println("b=", b, " b==nil:", b == nil) // b= <nil> b==nil: true fmt.Println("bp=", bp, " bp==nil:", bp == nil) //bp= <nil> bp==nil: true }
結(jié)構(gòu)體的 0 值為 {}
到此這篇關(guān)于golang 中的 nil的場景分析的文章就介紹到這了,更多相關(guān)golang 中的 nil內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言實現(xiàn)互斥鎖、隨機數(shù)、time、List
這篇文章主要介紹了Go語言實現(xiàn)互斥鎖、隨機數(shù)、time、List的相關(guān)資料,需要的朋友可以參考下2018-10-10Gin golang web開發(fā)模型綁定實現(xiàn)過程解析
這篇文章主要介紹了Gin golang web開發(fā)模型綁定實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10Golang基于泛化調(diào)用與Nacos實現(xiàn)Dubbo代理
這篇文章主要為大家詳細介紹了Golang如何基于泛化調(diào)用與Nacos實現(xiàn)Dubbo代理,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-04-04golang中strconv.ParseInt函數(shù)用法示例
這篇文章主要介紹了golang中strconv.ParseInt函數(shù)用法,實例分析了strconv.ParseInt函數(shù)將字符串轉(zhuǎn)換為數(shù)字的簡單使用方法,需要的朋友可以參考下2016-07-07Golang使用CGO與Plugin技術(shù)運行加載C動態(tài)庫
這篇文章主要介紹了Golang使用CGO與Plugin技術(shù)運行加載C動態(tài)庫,Golang?程序在運行時加載C動態(tài)庫的技術(shù),跳過了Golang項目編譯階段需要鏈接C動態(tài)庫的過程,提高了Golang項目開發(fā)部署的靈活性2022-07-07GO 函數(shù)式選項模式(Functional Options Pattern)
Option模式支持傳遞多個參數(shù),并且在參數(shù)個數(shù)、類型發(fā)生變化時保持兼容性,任意順序傳遞參數(shù),下面給大家介紹GO 函數(shù)式選項模式(Functional Options Pattern)的相關(guān)知識,感興趣的朋友一起看看吧2021-10-10