为什么golang在slice和map之间的`[]`操作符上实现不同的行为?

为什么golang在slice和map之间的`[]`操作符上实现不同的行为?,go,Go,a[0]可寻址,但b[0]不可寻址 我知道第一个0是索引,第二个0是键 戈朗为什么要这样做?还有进一步的考虑吗 我在中阅读了map的源代码,如果maxKeySize和maxValueSize足够小,那么map结构已经支持indirectkey和indirectvalue type S struct { e int } func main() { a := []S{{1}} a[0].e = 2 b := map[int]S{0: {1}} b[0].

a[0]可寻址,但b[0]不可寻址

我知道第一个
0
是索引,第二个
0
是键

戈朗为什么要这样做?还有进一步的考虑吗



我在中阅读了
map
的源代码,如果
maxKeySize
maxValueSize
足够小,那么map结构已经支持
indirectkey
indirectvalue

type S struct {
    e int
}

func main() {
    a := []S{{1}}
    a[0].e = 2

    b := map[int]S{0: {1}}
    b[0].e = 2 // error
}
我认为,如果golang设计师想要这种语法,现在就很容易了

当然,
indirectkey
indirectvalue
可能会花费更多的资源,GC也需要做更多的工作

那么性能是支持这一点的唯一原因

还是其他考虑

在我看来,支持这样的语法是很有价值的

据我所知

这是因为[0]可以替换为数组的地址

类似地,
a[1]
可以替换为
a[0]+(keySize*1)

但是,在map one不能这样做的情况下,哈希算法会根据您的键、值对和它们的数量不时地改变

它们也会不时地重新排列

为了得到值的地址,需要进行特定的计算

数组或片很容易寻址,但在映射的情况下,它就像多个函数调用或结构查找


如果一个人想用任何需要计算的东西来代替它,那么二进制的大小将在数量级上增加,此外,哈希算法还可以不断更改。

地图条目没有固定地址,因为它们可能会在地图变大/变小时移动。@Volker在这个问题中,我想了解更多关于地图和切片之间的golang设计,而不仅仅是实现。请取消dup标记好吗?@icza在这个问题中,我想了解更多关于地图和切片之间的golang设计,而不仅仅是实现。请取消dup标记好吗?关于Go的地图设计,除了语言规范中所说的:条目不可寻址之外,没有什么可以了解的了。对于技术问题,您为什么得到了答案。任何为什么或为什么不指定这一点都与SO无关。
indirectkey
indirectvalue
是golang现在支持的技术答案。还是我对源代码的理解有误?
type maptype struct {
    ...
    keysize       uint8  // size of key slot
    indirectkey   bool   // store ptr to key instead of key itself
    valuesize     uint8  // size of value slot
    indirectvalue bool   // store ptr to value instead of value itself
    ...
}