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 可以理解為這些類型的零值,聲明一個(gè)變量在沒有賦值的情況下,變量處于零值狀態(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 類型和值保持了一致所以會(huì)相等,但是 i 已經(jīng)不等于 nil 了,因?yàn)?nil 是 interface 的 0 值,或者說 i 已經(jīng)指向 p ,i 現(xiàn)在是個(gè)有類型狀態(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,這個(gè) 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 會(huì)拋錯(cuò) struct 不能和 nil 進(jìn)行比較 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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言實(shí)現(xiàn)互斥鎖、隨機(jī)數(shù)、time、List
這篇文章主要介紹了Go語言實(shí)現(xiàn)互斥鎖、隨機(jī)數(shù)、time、List的相關(guān)資料,需要的朋友可以參考下2018-10-10Gin golang web開發(fā)模型綁定實(shí)現(xiàn)過程解析
這篇文章主要介紹了Gin golang web開發(fā)模型綁定實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10Golang基于泛化調(diào)用與Nacos實(shí)現(xiàn)Dubbo代理
這篇文章主要為大家詳細(xì)介紹了Golang如何基于泛化調(diào)用與Nacos實(shí)現(xiàn)Dubbo代理,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-04-04使用Go語言實(shí)現(xiàn)一個(gè)簡單的無界資源池
本文我們希望通過go語言實(shí)現(xiàn)一個(gè)簡單的資源池,而這個(gè)資源池的資源包括但不限于數(shù)據(jù)庫連接池,線程池,協(xié)程池,網(wǎng)絡(luò)連接池,只要這些資源實(shí)現(xiàn)我們指定的關(guān)閉方法,則都可以通過我們封裝的資源池進(jìn)行統(tǒng)一管理,文中通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05淺析如何利用Go的plugin機(jī)制實(shí)現(xiàn)熱更新
熱更新,或稱熱重載或動(dòng)態(tài)更新,是一種軟件更新技術(shù),允許程序在運(yùn)行時(shí),不停機(jī)更新代碼或資源,本文主要來討論下GO語言是否可以利用plugin機(jī)制實(shí)現(xiàn)熱更新,感興趣的可以了解下2024-04-04golang中strconv.ParseInt函數(shù)用法示例
這篇文章主要介紹了golang中strconv.ParseInt函數(shù)用法,實(shí)例分析了strconv.ParseInt函數(shù)將字符串轉(zhuǎn)換為數(shù)字的簡單使用方法,需要的朋友可以參考下2016-07-07Golang使用CGO與Plugin技術(shù)運(yùn)行加載C動(dòng)態(tài)庫
這篇文章主要介紹了Golang使用CGO與Plugin技術(shù)運(yùn)行加載C動(dòng)態(tài)庫,Golang?程序在運(yùn)行時(shí)加載C動(dòng)態(tài)庫的技術(shù),跳過了Golang項(xiàng)目編譯階段需要鏈接C動(dòng)態(tài)庫的過程,提高了Golang項(xiàng)目開發(fā)部署的靈活性2022-07-07GO 函數(shù)式選項(xiàng)模式(Functional Options Pattern)
Option模式支持傳遞多個(gè)參數(shù),并且在參數(shù)個(gè)數(shù)、類型發(fā)生變化時(shí)保持兼容性,任意順序傳遞參數(shù),下面給大家介紹GO 函數(shù)式選項(xiàng)模式(Functional Options Pattern)的相關(guān)知識(shí),感興趣的朋友一起看看吧2021-10-10