nil的特点
-
是Go语言中一个预定义好的标识符
-
是"指针、切片、映射、通道、函数、接口的零值"
nil与null不同点
nil标识符是不能比较的
==
对于 nil 来说是一种未定义的操作
package main
?
import "fmt"
?
func main() {
fmt.Println(nil == nil)
}
/*
会提示
# command-line-arguments
.\NilPractice.go:6:18: invalid operation: nil == nil (operator == not defined on nil)
*/
nil不是关键字或保留字
可以定义一个名为nil
的变量
package main
?
import "fmt"
?
func main() {
nil := "Hello"
fmt.println(nil)
/*这在Go语言中是合法的*/
}
nil没有默认类型
package main
?
import "fmt"
?
func main() {
fmt.Printf("%T", nil)
print(nil)
}
不同类型nil的指针是一样的
package main
?
import "fmt"
?
func main() {
/*声明两个变量*/
var arr []int
var num *int
?
/*分别利用格式化输出他们的nil值*/
fmt.Printf("%p\n", arr)
fmt.Printf("%p", num)
/*
fmt.Printf方法返回一个整数类型的值
和常规的空值验证
*/
}
//arr 和 num 的指针都是 0x0
指针指向的内存地址不一样:
package main
?
import "fmt"
?
func main() {
/*声明两个变量*/
var arr []int
var num *int
?
/*分别利用格式化输出他们的nil值*/
fmt.Printf("%p\n", &arr)
fmt.Printf("%p", &num)
/*
fmt.Printf方法返回一个整数类型的值
和常规的空值验证
*/
}
//这两个的结果是不一样的
不同类型的nil值不能比较
package main
?
import "fmt"
?
func main() {
/*声明两个变量*/
var mapValue map [int] string
var ptr *int
?
fmt.Printf(mapValue == ptr)
}
/*
这会导致编译无法通过
*/
两个相同类型的nil值也可能无法比较
map、slice 和 function 类型的 nil 值不能比较。会导致编译不通过
package main
?
import "fmt"
?
func main() {
/*声明两个切片*/
var num1 []int
var num2 []int
fmt.Printf(num1 == num2)
fmt.Printf(num1 == nil) //这也会导致编译无法通过--->不能将空值直接与nil标识符进行比较
}
nil 是 map、slice、func、pointer、channel、interface 的零值
package main
import (
"fmt"
)
func main() {
var m map[int]string
var ptr *int
var c chan int
var sl []int
var f func()
var i interface{}
fmt.Printf("%#v\n", m)
fmt.Printf("%#v\n", ptr)
fmt.Printf("%#v\n", c)
fmt.Printf("%#v\n", sl)
fmt.Printf("%#v\n", f)
fmt.Printf("%#v\n", i)
}
不同类型的nil值占用的内存大小可能是不一样的
-
一个类型的所有的值的内存布局都是一样的,nil 的大小与同类型中的非 nil 类型的大小是一样的。
-
不同类型的 nil 值的大小可能不同。
package main
import (
"fmt"
"unsafe"
)
func main() {
var p *struct{}
fmt.Println( unsafe.Sizeof( p ) ) // 8
var s []int
fmt.Println( unsafe.Sizeof( s ) ) // 24
var m map[int]bool
fmt.Println( unsafe.Sizeof( m ) ) // 8
var c chan string
fmt.Println( unsafe.Sizeof( c ) ) // 8
var f func()
fmt.Println( unsafe.Sizeof( f ) ) // 8
var i interface{}
fmt.Println( unsafe.Sizeof( i ) ) // 16
}
总结
-
nil不是Go语言当中预先定义好的标识符或保留字,可以作为变量名
-
不同类型的nil无法比较,相同类型的nil有可能也无法比较
-