golang的map类型是一个比较特殊的类型,不同于int, string, byte这样的基本类型,在经过一番探究之后得出了一些结论:
1、golang的map类型虽然是内置类型,但和基本类型有很大区别,更像是一个指针,因为他有着跟指针一样行为。
下面这段代码的第三次输出时,尝试了用通过arr[1].c["aaa"] = "lalala",这种方式去修改这个map元素,发现arr[0]同时被改变了。这也就说明了arr里面保存的其实是指向一块内存的指针,所以在通过arr[1].c["aaa"] = "lalala"这种方式修改时,arr[0]也同时被修改了。
2、修改arr[1]的时候,同时也修改了int类型的a,但是arr[0]却没有同时被更改,这可以说明两点。
a. append函数在追加arr数组时,传递给append函数的参数是一个实体,而不是指针或引用
b. 在拷贝Node实体时,int类型的a是被深拷贝的,也就是拷贝了 一个实体,而map只是被拷贝了指针(扯不清楚,就是那个意思)
综合以上两个结论可以得出:我们其实可以把map看成是一个指针对象,这样就可以防止不正确的使用方式带来的隐患了
// 定义了一个结构体
type Node struct {
a int
c map[string]string
}
// 定义了一个Node类型的数组
arr := make([]Node, 0)
x := Node{}
x.a = 1
x.c = make(map[string]string, 0)
x.c["aaa"] = "bbb"
arr = append(arr, x) //将一个Node对象追加到 arr 数组
//-------第一次输出--------//
fmt.Println(arr)
x.a = 3 // 将同一个Node对象修改之后再次追加
x.c["aaa"] = "ccc"
x.c["dlskjfd"] = "dlkfsd"
arr = append(arr, x)
//-------第二次输出--------//
fmt.Println(arr)
arr[1].a = 34
arr[1].c["aaa"] = "lalalala"
//-------第三次输出--------//
fmt.Println(arr)
[{1 map[aaa:bbb]}]
[{1 map[aaa:ccc dlskjfd:dlkfsd]} {3 map[aaa:ccc dlskjfd:dlkfsd]}]
[{1 map[aaa:lalalala dlskjfd:dlkfsd]} {34 map[aaa:lalalala dlskjfd:dlkfsd]}]