Gre*_*ine 6 struct map go slice
假设我有一个带字符串属性b的简单结构a:
type A struct {
B string
}
Run Code Online (Sandbox Code Playgroud)
以下代码使用A类型的数组:
testArray := []A{A{}}
testArray[0].B = "test1"
fmt.Println(testArray[0].B)
Run Code Online (Sandbox Code Playgroud)
将按预期打印出"test1".
但是这段代码似乎同样简单:
testMap := make(map[string]A)
testMap["key"] = A{}
testMap["key"].B = "test2"
fmt.Println(testMap["key"].B)
Run Code Online (Sandbox Code Playgroud)
不会打印出"test2",而是会导致以下错误:
无法分配到testMap ["key"].B
那么,为什么分配给映射中的子属性会导致错误,同时分配给数组中的子属性按预期工作?我想知道为什么这对地图不起作用以及为什么它对数组起作用.我也很想知道他们为什么设计这两种数据结构之间存在差异的语言.
ian*_*ant 11
我在邮件列表上回答了一些问题,但简短的解释是这不起作用,因为地图条目不可寻址.这意味着您无法获取地图中条目的地址.这是因为向地图添加新值可能会导致地图条目四处移动,从而地址会发生变化.由于您无法获取地图中条目的地址,因此所有地图操作都使用整个值:从地图复制整个值,将整体添加到地图中.分配给映射中的结构的一个字段将需要读取 - 修改 - 写入操作,映射不支持(它们可以,但它们不支持,并且支持它们需要成本).
数组和切片中的元素是可寻址的,因为它们在创建后不会移动.
问题是在 map 示例中,testMap["key"]
返回的是文字,而不是指针。这意味着修改它是没有意义的,所以编译器不允许它。它基本上相当于:
v := testMap["key"]
v.B = "test2"
Run Code Online (Sandbox Code Playgroud)
...然后再也不使用v
了。它没有效果。这相当于从不首先执行这两行。这就是编译器不允许你这样做的原因。另一方面,如果你把它做成一个指向A的指针的映射,你就会做生意。这将编译:
testMap := make(map[string]*A)
testMap["key"] = &A{}
testMap["key"].B = "test2"
Run Code Online (Sandbox Code Playgroud)
这样做的原因是取消引用和分配给一个指针值确实有效果。
归档时间: |
|
查看次数: |
4983 次 |
最近记录: |