(1)从map中取值问题
可以对未初始化的map进行取值,但取值来的是对应类型的零值。但不能对未初始化的map进行赋值,会抛异常
var m1 map[int]string
var m2 map[int]int
fmt.Println(m1[111] == "") //true
fmt.Println(m2[111] == 0) //true
m1[0] = "23" //panic: assignment to entry in nil map
从map中取值可以有一个或者两个返回值。第二个返回值可选,表示key是否存在。
m := make(map[int]string)
m[0] = "123"
key1 := m[0]
key2, exist := m[0]
fmt.Println(key1, key2, exist)
需要注意的是,从map里取值,返回的始终是值所对应的副本,并不是值本身。验证:
func main() {
students := make(map[int]student)
students[0] = student{name: "test"}
//students := make(map[int]*student)
//students[0] = &student{name: "test"}
stu, exist := students[0]
if exist {
stu.name = "changed"
}
fmt.Println(students[0].name)
}
type student struct {
name string
}
这里控制台打印了test。如果想改变原来的值,需要使用指针。
还需要注意一点,将切片或者map传递给函数成本很小,不会复制底层的数据结构,但是将数组传递给函数,会复制,要尽量避免给函数传递数组。
(2)函数中defer的用法
函数中使用defer关键字,会在函数返回时才执行,即使函数报错也会执行。
func main() {
var m1 map[int]string
defer end()
fmt.Println("execute before defer")
m1[0] = "test" //panic: assignment to entry in nil map
}
func end() {
fmt.Println("this is end")
}
输出
execute before defer
this is end
panic: assignment to entry in nil map