请教为啥无法获取`stus["a"]`的指针
```
type Student struct {
Name string
}
func main() {
stus := make(map[string]Student)
stus["a"] = Student{"a"}
p := &stus["a"] //cannot take the address of stus["a"]
}
```
更多评论
这是因为stus["a"]的返回值不是固定的地址, 算不出来吧, 因为每次都要复制一次.
你如果把stus["a"]赋值给一个栈变量就可以了.
```go
s := stus["a"]
//p := stus["a"] //cannot take the address of stus["a"]
p := &s // 这样就不会报错了
```
#1
详细请看 [Go101的问答 - 为什么映射元素不可被取地址?](https://gfw.go101.org/article/unofficial-faq.html#map-elements-are-unaddressable)
> # 为什么映射元素不可被取地址?
在Go中,映射的设计保证一个映射值在内存允许的情况下可以加入任意个条目。 另外为了防止一个映射中为其条目开辟的内存段支离破碎,官方标准编译器使用了哈希表来实现映射。 并且为了保证元素索引的效率,一个映射值的底层哈希表只为其中的所有条目维护一段连续的内存段。 因此,一个映射值随着其中的条目数量逐渐增加时,其维护的连续的内存段需要不断重新开辟来增容,并把原来内存段上的条目全部复制到新开辟的内存段上。 另外,即使一个映射值维护的内存段没有增容,某些哈希表实现也可能在当前内存段中移动其中的条目。 总之,映射中的元素的地址会因为各种原因而改变。 如果映射元素可以被取地址,则Go运行时(runtime)必须在元素地址改变的时候修改所有存储了元素地址的指针值。 这极大得增加了Go编译器和运行时的实现难度,并且严重影响了程序运行效率。 因此,目前,Go中禁止取映射元素的地址。
> 映射元素不可被取地址的另一个原因是表达式aMap[key]可能返回一个存储于aMap中的元素,也可能返回一个不存储于其中的元素零值。 这意味着表达式aMap[key]在(&aMap[key]).Modify()调用执行之后可能仍然被估值为元素零值。 这将使很多人感到困惑,因此在Go中禁止取映射元素的地址。
#3