nil主要是作为slice、map、函数、指针、interface的零值,使用时有两点需要注意:
一、slice的元素清空
package main
import (
"fmt"
)
func main() {
var testList []int
fmt.Println("testList1=", testList)
testList = append(testList, 1)
fmt.Println("testList2=", testList)
testList = nil // 清空数据
testList = append(testList, 2) // 如果按照c++的套路,给空值赋值是要报段错误的,而这里是正常的
fmt.Println("testList3=", testList)
}
代码输出如下:
testList1= []
testList2= [1]
testList3= [2]
分析:
nil值本来就是slice的零值,因此清空元素可以直接用nil赋值,清空后可以正常使用;
二、接口类型的nil值判断
只有当接口的类型
和值
,同时为nil时,才能判断接口为nil, 示例代码如下:
package main
import (
"fmt"
)
type Person struct {
name string
}
func testFunc1(num int) interface{} {
if 1 == num {
return &Person{"AAA"}
}
return nil // 注意这里的返回值
}
func testFunc2(num int) interface{} {
var persion *Person
if 1 == num {
persion = &Person{"AAA"}
}
return persion // 注意这里的返回值
}
func main() {
result1 := testFunc1(2)
if result1 != nil {
fmt.Println("result1: not nil")
} else {
// 值和类型都是nil
fmt.Println("result1: is nil")
}
result2 := testFunc2(2)
if result2 != nil {
// 值是nil, 但类型是*Persion类型
fmt.Println("result2: not nil")
persion, ok := result2.(*Person)
if !ok {
fmt.Println("result2: not Persion type")
} else {
fmt.Println("result2: is Persion Type, person=", persion)
}
} else {
fmt.Println("result2: is nil")
}
}
执行结果如下:
result1: is nil
result2: not nil
result2: is Persion Type, person= <nil>
分析:
testFunc1返回的是nil, 所以类型和值都是nil;
testFunc2返回的是*Person类型的指针,只有值是nil;