Golang学习日志 ━━ map等类型的指针分析

学习时遇到了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: 1

v1[10010].age = 2
fmt.Println("v1[10010].age:", v1[10010].age) // v1[10010].age: 2

fmt.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

//==============================测试map
var 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 0xc00006ebd0
fmt.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 0xc000004760
fmt.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 0xc000004760
fmt.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

在这里插入图片描述

学习资料

GoLang基础数据类型—>字典(map)详解
Golang中哪些值是不可以寻址的
Golang map 的底层实现
Go语言map底层浅析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Golang 中,可以使用指针来操作 map。当我们传递 map 作为参数时,实际上是传递了 map 的一个副本。如果需要修改原始 map,可以传递 map指针,或者在函数内部返回 map指针。 以下是一个使用 map 指针的示例代码: ```go package main import "fmt" func main() { m := make(map[string]int) m["a"] = 1 m["b"] = 2 // 传递 map指针 addValue(&m, "c", 3) fmt.Println(m) // 输出:map[a:1 b:2 c:3] // 返回 map指针 m2 := createMap() fmt.Println(m2) // 输出:map[x:10 y:20 z:30] } func addValue(m *map[string]int, key string, value int) { (*m)[key] = value } func createMap() *map[string]int { m := make(map[string]int) m["x"] = 10 m["y"] = 20 m["z"] = 30 return &m } ``` 在上面的示例中,我们定义了两个函数,`addValue` 和 `createMap`,分别演示了如何传递 map指针和返回 map指针。在 `addValue` 函数中,我们使用 `*` 操作符来获取 map指针,并修改了原始的 map。在 `createMap` 函数中,我们使用 `&` 操作符来返回 map指针。 ### 回答2: 在Go语言中,map是一种无序的键值对集合,可以用于存储和检索数据。默认情况下,map是通过值传递的,即将map赋值给另一个变量时,会复制一份map的副本。但我们也可以使用指针来操作map,从而可以在函数间共享和修改同一个map。 使用指针来操作map有两种常见的方式。一种是直接声明一个指向map指针变量,然后通过间接引用来操作map。例如: ```go var m *map[string]int // 声明指向map指针变量 m = &map[string]int{} // 创建一个空的map,并将其地址赋值给指针变量 (*m)["key"] = 123 // 通过指针间接引用map,并修改其值 ``` 另一种方式是使用make函数创建一个map,并将其指针传递给函数。例如: ```go func modifyMap(m *map[string]int) { (*m)["key"] = 123 // 通过指针间接引用map,并修改其值 } func main() { m := make(map[string]int) // 创建一个map modifyMap(&m) // 将map指针传递给函数 } ``` 需要注意的是,在使用指针操作map时,要确保map已经被初始化。否则,会发生运行时错误。另外,由于map本身就是引用类型,因此大部分情况下,直接使用map而不是指针就可以满足需求,而且更加简单和安全。只有在需要在函数间传递和修改同一个map时,才需要使用指针来操作map。 ### 回答3: Golang中的map是一种无序的键值对集合,而map指针则是指向map的内存地址的指针。 在使用map时,可以通过var关键字声明一个map变量,并使用make函数来初始化该map。而如果需要使用map指针,可以通过将map变量的地址赋值给指针变量来实现。 下面是一个示例代码: ``` package main import "fmt" func main() { // 声明并初始化map myMap := make(map[string]int) myMap["apple"] = 2 myMap["banana"] = 3 // 声明并初始化map指针 var myMapPtr *map[string]int myMapPtr = &myMap // 使用map指针修改map (*myMapPtr)["apple"] = 5 // 输出修改后的值 fmt.Println(myMap["apple"]) } ``` 在上述代码中,首先使用make函数初始化了一个map变量myMap,并给其中的键"apple"和"banana"分别赋值。然后,使用var关键字声明了一个map指针myMapPtr,并将myMymap的地址赋值给了myMapPtr。接下来,使用map指针修改了map中键"apple"的值为5。最后,输出了map中键"apple"的值,结果为5。 总结来说,Golangmap指针允许我们通过指针来修改和访问map的值,更灵活地操作Map的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值