1.map简介:
map 是go语言的一种基础类型。对map作为参数的函数中修改map的值,应该传指向该map地址还是直接传该map呢?其实无论你一那种方式进行参数传递都会改变其值。
2.创建map:
创建map又一下几种方法:
package main
import (
"fmt"
)
func main(){
map1 := make(map[string]int)
map2 := map[string]int{}
var map3 map[string]int
fmt.Printf("%#v\n",map1)
fmt.Printf("%#v\n",map2)
fmt.Printf("%#v\n",map3)
}
make方法创建map1,创建时已经初始化
map2常用的声明变量方式,创建时初始化
var 可用于包内任意地方的声明。
打印输出:
map[string]int{}
map[string]int{}
map[string]int(nil)
map的新增键值对也很简单,但是的注意声明时候的类型约束。
package main
import (
"fmt"
)
func main(){
map1 := make(map[string]int)
map2 := map[string]int{}
var map3 map[string]int
map1["map1"] = 1
map2["map2"] = 2
map3["map3"] = 3
fmt.Printf("%#v\n",map1)
fmt.Printf("%#v\n",map2)
fmt.Printf("%#v\n",map3)
}
这段代码很简单但是却有一个常见的错误。先看运行结果:
panic: assignment to entry in nil map
goroutine 1 [running]:
main.main()
/home/golang/config/main.go:13 +0xbb
对13行报错,也就是map3未进行初始化,所以添加时候就会出现panic.
下面改一下代码
package main
import (
"fmt"
)
func main(){
map1 := make(map[string]int)
map2 := map[string]int{}
var map3 map[string]int = map2
map1["map1"] = 1
map2["map2"] = 2
map3["map3"] = 3
fmt.Printf("%#v\n",map1)
fmt.Printf("%#v\n",map2)
fmt.Printf("%#v\n",map3)
}
运行结果可能会令初学者感到诧异:
map[string]int{"map1":1}
map[string]int{"map2":2, "map3":3}
map[string]int{"map2":2, "map3":3}
没错,map2和map3的结果完全一摸一样。
我们在打印一个每个map的地址。
package main
import (
"fmt"
)
func main(){
map1 := make(map[string]int)
map2 := map[string]int{}
var map3 map[string]int = map2
map1["map1"] = 1
map2["map2"] = 2
map3["map3"] = 3
fmt.Printf("%p\n",map1)
fmt.Printf("%p\n",map2)
fmt.Printf("%p\n",map3)
}
运行结果为:
0xc000096150
0xc000096180
0xc000096180
清晰的看到map2和map3的地址时相同的
那对于指向map的指针呢。
package main
import (
"fmt"
)
func testChangeMap(m *map[string]int){
(*m)["map1"] = 2
}
func main(){
map1 := &map[string]int{"map1": 1}
testChangeMap(map1)
fmt.Println(map1)
}
运行结果:
&map[map1:2]
我们看到这种方法完全没有问题,
再看一段代码:
package main
import (
"fmt"
)
func testChangeMap(m *map[string]int){
v := *m
v["map1"]=2
}
func main(){
map1 := &map[string]int{"map1": 1}
testChangeMap(map1)
fmt.Println(map1)
}
运行结果:
&map[map1:2]
依旧没有问题。
但是我们尝试去打印一下v和map1的地址
package main
import (
"fmt"
)
func main(){
map1 := &map[string]int{"map1":1}
v := *map1
v["map1"]=2
fmt.Printf("%p\n",v)
fmt.Printf("%p\n",map1)
}
运行结果:
0xc000096150
0xc0000ac018
可以看到两个地址完全不同,但是我改变了v中key "map1"的值,确实map1的值:
这是因为map1实际是存放了是一个地址的值,那么我们在修改一下代码:
package main
import (
"fmt"
)
func main(){
map1 := &map[string]int{"map1":1}
v := *map1
v["map1"]=2
fmt.Printf("%p\n",v)
fmt.Printf("%p\n",*map1)
}
运行结果:
0xc000066150
0xc000066150
输出结果一摸一样,map就是对底层的一种应用。
所以map作为参数无论你是以地址的方式传参,还是以map直接传参都会改变其值。