日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Go 学习笔记(28)— nil(nil 不能比较、不是关键字或保留字、nil 没有默认类型、不同类型的 nil 指针是一样的、不同类型的 nil 是不能比较的、相同类型的 nil 可能也无法比较)

發布時間:2023/11/27 生活经验 25 豆豆

Go 語言中,布爾類型的零值(初始值)為 false ,數值類型的零值為 0,字符串類型的零值為空字符串 "",而指針、切片、映射、通道、函數和接口的零值則是 nil

nilGo 語言中一個預定義好的標識符,有過其他編程語言開發經驗的開發者也許會把 nil 看作其他語言中的 nullNULL ),其實這并不是完全正確的,因為 Go 語言中的 nil 和其他語言中的 null 有很多不同點。

下面通過幾個方面來介紹一下 Go 語言中 nil

1. nil 標識符是不能比較的

package mainimport ("fmt"
)func main() {fmt.Println(nil == nil)
}

輸出結果:

# command-line-arguments
./hello.go:8:18: invalid operation: nil == nil (operator == not defined on nil)

這點和 python 等動態語言是不同的,在 python 中,兩個 None 值永遠相等。

>>> None == None
True
>>> 

從上面的運行結果不難看出, == 對于 nil 來說是一種未定義的操作。

2. nil 不是關鍵字或保留字

nil 并不是 Go 語言的關鍵字或者保留字,也就是說我們可以定義一個名稱為 nil 的變量,比如下面這樣:

var nil = errors.New("my god")

雖然上面的聲明語句可以通過編譯,但是并不提倡這么做。

3. nil 沒有默認類型

package mainimport ("fmt"
)func main() {fmt.Printf("%T", nil)print(nil)
}

輸出結果:

# command-line-arguments
./hello.go:9:7: use of untyped nil

4. 不同類型 nil 的指針是一樣的

package mainimport ("fmt"
)func main() {var arr []intvar num *intfmt.Printf("%p\n", arr)fmt.Printf("%p", num)
}

輸出結果:

0x0
0x0

通過運行結果可以看出 arrnum 的指針都是 0x0。

5. 不同類型的 nil 是不能比較的

package mainimport ("fmt"
)func main() {var m map[int]stringvar ptr *intfmt.Printf(m == ptr)
}

輸出結果:

# command-line-arguments
./hello.go:10:15: invalid operation: m == ptr (mismatched types map[int]string and *int)

6. 兩個相同類型的 nil 值也可能無法比較

Go 語言中 mapslicefunction 類型的 nil 值不能比較,比較兩個無法比較類型的值是非法的,下面的語句無法編譯。

package mainimport ("fmt"
)func main() {var s1 []intvar s2 []intfmt.Printf(s1 == s2)
}

輸出結果:

# command-line-arguments
./hello.go:10:16: invalid operation: s1 == s2 (slice can only be compared to nil)

通過上面的錯誤提示可以看出,能夠將上述不可比較類型的空值直接與 nil 標識符進行比較,如下所示:

package mainimport ("fmt"
)func main() {var s1 []intfmt.Println(s1 == nil)	// true
}

7. nil 是 map、slice、pointer、channel、func、interface 的零值

package mainimport ("fmt"
)func main() {var m map[int]stringvar ptr *intvar c chan intvar sl []intvar f func()var i interface{}fmt.Printf("%#v\n", m)   // map[int]string(nil)fmt.Printf("%#v\n", ptr) // (*int)(nil)fmt.Printf("%#v\n", c)   // (chan int)(nil)fmt.Printf("%#v\n", sl)  // []int(nil)fmt.Printf("%#v\n", f)   // (func())(nil)fmt.Printf("%#v\n", i)   // <nil>
}

零值是 Go 語言中變量在聲明之后但是未初始化被賦予的該類型的一個默認值。

8. 不同類型的 nil 值占用的內存大小可能是不一樣的

一個類型的所有的值的內存布局都是一樣的, nil 也不例外, nil 的大小與同類型中的非 nil 類型的大小是一樣的。但是不同類型的 nil 值的大小可能不同。

package mainimport ("fmt""unsafe"
)func main() {var p *struct{}fmt.Println(unsafe.Sizeof(p)) // 8var s []intfmt.Println(unsafe.Sizeof(s)) // 24var m map[int]boolfmt.Println(unsafe.Sizeof(m)) // 8var c chan stringfmt.Println(unsafe.Sizeof(c)) // 8var f func()fmt.Println(unsafe.Sizeof(f)) // 8var i interface{}fmt.Println(unsafe.Sizeof(i)) // 16
}

具體的大小取決于編譯器和架構,上面打印的結果是在 64 位架構和標準編譯器下完成的,對應 32 位的架構的,打印的大小將減半。

總結

以上是生活随笔為你收集整理的Go 学习笔记(28)— nil(nil 不能比较、不是关键字或保留字、nil 没有默认类型、不同类型的 nil 指针是一样的、不同类型的 nil 是不能比较的、相同类型的 nil 可能也无法比较)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。