一尘不染

为什么映射值不可寻址?

go

在玩Go代码时,我发现映射值不可寻址。例如,

package main
import "fmt"

func main(){
    var mymap map[int]string = make(map[int]string)
    mymap[1] = "One"
    var myptr *string = &mymap[1]
    fmt.Println(*myptr)
}

产生错误

mapaddressable.go:7:无法获取mymap [1]的地址

而代码,

package main
import "fmt"

func main(){
    var mymap map[int]string = make(map[int]string)
    mymap[1] = "One"
    mystring := mymap[1]
    var myptr *string = &mystring
    fmt.Println(*myptr)
}

工作完美。

为什么会这样呢?为什么Go开发人员选择使某些值无法解决?这是语言的缺点还是功能?

编辑 :来自C ++背景,我不习惯于这种not addressable流行趋势。例如,以下代码可以正常工作:

#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(){
    map<int,string> mymap;
    mymap[1] = "one";
    string *myptr = &mymap[1];
    cout<<*myptr;
}

如果有人可以指出为什么在Go中无法实现(或故意没有实现)相同的 寻址 能力,那就太好了。


阅读 229

收藏
2020-07-02

共1个答案

一尘不染

好吧,我不知道地图的内部Go实现,但很可能它是一种哈希表。因此,如果您获取并保存其中一个条目的地址,然后再放入其他条目,则您保存的地址可能无效。这是由于当负载系数超过某个阈值并且哈希表需要增长时,哈希表的内部重组。
因此,我猜不允许它采用其中一项的地址以避免这种错误。

2020-07-02