- golang cannot assign to XXX 问题分析
- 【gerrit】Cannot assign user name
- Golang cannot assign to arrays i
- Cannot assign requested address出
- 这个 TCP 问题你得懂:Cannot assign reque
- 在GPU上使用Tensorflow出现Cannot assign
- setState问题 Cannot assign to read
- Cannot assign to 'self' outside
- kafka与Flink集成问题记录
- 【完美解决】Hexo博客出现“Cannot GET/xxx”错误
今天在编译golang项目时,遇到了一个错误。编译器提示 cannot assign to m[1][1]
原项目太大了,不贴了代码大体是这样的
package main
func main() {
m := make(map[int][2]int)
a := [2]int{1, 2}
m[1] = a
m[1][1] = 3
}
编译器提示,不能取到m[1][1]的地址。
但是使用 fmt 能打印出数值
package main
import "fmt"
func main() {
m := make(map[int][2]int)
a := [2]int{1, 2}
m[1] = a
// m[1][1] = 3
fmt.Println(m[1][1])
}
打印结果
想了一下,go中的数组和切片(Slice)的和数组(Array)是不一样的,slice是引用传递,array是值传递。把 a
换成slice试一下
代码如下:
package main
import "fmt"
func main() {
m := make(map[int][]int)
a := []int{1, 2}
m[1] = a
m[1][1] = 3
fmt.Println(m[1][1])
}
编译通过,没有问题。
问题找到了,是因为值传递导致的问题,解决办法有三种
1 . 像上面一样,使用slice代替array。
2 . 不直接修改数组的值,修改值时,重新创建数组:
package main
import "fmt"
func main() {
m := make(map[int][2]int)
a := [2]int{1, 2}
m[1] = a
fmt.Println(m)
b := [2]int{3, 4}
m[1] = b
fmt.Println(m)
}
结果如下:
3 .使用指向数组的指针:
package main
import "fmt"
func main() {
m := make(map[int]*[2]int)
a := &[2]int{1, 2}
m[1] = a
fmt.Println(m[1])
m[1][1] = 3
fmt.Println(m[1])
}
结果如下:
没有问题,可以修改值
在网上搜索没有找到深入点分析的文章,最终在stack overflow中找到了一个挺好的分析传送门
原文:
p["HM"]
isn't quite a regular addressable value: hashmaps can grow at runtime, and then their values get moved around in memory, and the old locations become outdated. If values in maps were treated as regular addressable values, those internals of themap
implementation would get exposed.
英文比较渣,大体看懂了一点意思。我理解的,应该是在程序执行过程中map的长度会变化,为了map值的正确,go语言不允许直接修改map中的值类型结构。
在想另一种情况:
package main
import "fmt"
func main() {
m := make(map[int]T)
t := T{
One: 1,
Two: 2,
}
m[1] = t
fmt.Println(m)
m[1].Two = 3
fmt.Println(m[1])
}
type T struct {
One int
Two int
}
运行:
编译器提示同样的错误
换成指针后:
package main
import "fmt"
func main() {
m := make(map[int]*T)
t := &T{
One: 1,
Two: 2,
}
m[1] = t
fmt.Println(m[1])
m[1].Two = 3
fmt.Println(m[1])
}
type T struct {
One int
Two int
}
运行:
网友评论