本文共 2875 字,大约阅读时间需要 9 分钟。
学习时遇到了map内含结构体,却不能使用map[string].int=1
的方式进行直接修改,查了一下是因为golang出于安全原因,将map中的索引的值设定为不可寻址,即意味着无法直接修改该map索引下结构体内的字段。
解决方法也很简单,其中一种就是让map记住结构体的指针,而不是结构体本身。这样根据结构体指针就能找到该结构体及其字段了。
type archive struct { name string age int}v1 := map[int64]*archive{ 10010: &archive{ name: "xiaoli", age: 1, },}fmt.Println("v1[10010].age:", v1[10010].age) // v1[10010].age: 1v1[10010].age = 2fmt.Println("v1[10010].age:", v1[10010].age) // v1[10010].age: 2fmt.Printf("v1:%v %T %p\n", v1, v1, v1)// v1:map[10010:0xc000004660] map[int64]*pkg.archive 0xc00006eb70
写了如下的代码再看了一遍几种指针的情况,确实map与众不同。
//==============================测试普通var m0 = int64(101)fmt.Printf("m0:%v %T %p\n", m0, m0, m0) // m0:101 int64 %!p(int64=101)fmt.Printf("&m0:%v %T %p\n", &m0, &m0, &m0) // &m0:0xc00000c318 *int64 0xc00000c318//==============================测试mapvar m1 = map[string]int{ "a": 1, "b": 2}fmt.Printf("m1:%v %T %p\n", m1, m1, m1) // m1:map[a:1 b:2] map[string]int 0xc00006ebd0fmt.Printf("&m1:%v %T %p\n", &m1, &m1, &m1) // &m1:&map[a:1 b:2] *map[string]int 0xc000006030// map类型不能获得索引地址,即不可取地址// pkg\keng_ShowMapNoaddress.go:14:8: cannot take the address of m1["a"]// m3 := &m1["a"]// fmt.Printf("m3:%v %T\n", m3, m3)//==============================测试切片// 与map类型一样var s1 = []string{ "a", "b"}fmt.Printf("s1:%v %T %p\n", s1, s1, s1) // s1:[a b] []string 0xc000004760fmt.Printf("&s1:%v %T %p\n", &s1, &s1, &s1) // &s1:&[a b] *[]string 0xc000004740// slice类型可以获得索引值得地址fmt.Printf("&s1[0]:%v %T %p\n", &s1[0], &s1[0], &s1[0]) // &s1[0]:0xc000004760 *string 0xc000004760fmt.Printf("&s1[1]:%v %T %p\n", &s1[1], &s1[1], &s1[1]) // &s1[1]:0xc000004770 *string 0xc000004770//==============================测试结构体type st struct { name string age int}var st1 = st{ name: "a", age: 1,}var st2 = st{ name: "b", age: 2,}type stt struct { address string st}var stt1 = stt{ address: "地址", st: st2,}// 和普通一样,就是本例中的m0,%p不可,与map和slice不同fmt.Printf(" st1:%v %T %p\n st2:%v %T %p\n stt1:%v %T %p\n", st1, st1, st1, st2, st2, st2, stt1, stt1, stt1)// st1:{a 1} pkg.st %!p(pkg.st={a 1})// st2:{b 2} pkg.st %!p(pkg.st={b 2})// stt1:{地址 {b 2}} pkg.stt %!p(pkg.stt={地址 {b 2}}) fmt.Printf(" &st1:%v %T %p\n &st2:%v %T %p\n &stt1:%v %T %p\n", &st1, &st1, &st1, &st2, &st2, &st2, &stt1, &stt1, &stt1)// &st1:&{a 1} *pkg.st 0xc000004800// &st2:&{b 2} *pkg.st 0xc000004820// &stt1:&{地址 {b 2}} *pkg.stt 0xc00006ed20 // 可以获得结构体内,包括嵌套结构体内的字段所在地址fmt.Printf(" &st1.name:%v %T %p\n &st2.name:%v %T %p\n &stt1.address:%v %T %p\n &stt1.st.name:%v %T %p\n", &st1.name, &st1.name, &st1.name, &st2.name, &st2.name, &st2.name, &stt1.address, &stt1.address, &stt1.address, &stt1.st.name, &stt1.st.name, &stt1.st.name)// &st1.name:0xc000004800 *string 0xc000004800// &st2.name:0xc000004820 *string 0xc000004820// &stt1.address:0xc00006ed20 *string 0xc00006ed20// &stt1.st.name:0xc00006ed30 *string 0xc00006ed30
转载地址:http://tvkpi.baihongyu.com/