无法分配给地图中的结构字段

分享于2022年07月17日 go 问答
【问题标题】:无法分配给地图中的结构字段(Cannot assign to struct field in a map)
【发布时间】:2022-03-17 01:36:13
【问题描述】:

我有这样的数据结构:

type Snapshot struct {
  Key   string
  Users []Users
}

snapshots := make(map[string] Snapshot, 1)

// then did the initialization
snapshots["test"] = Snapshot {
  Key: "testVal",
  Users: make([]Users, 0),
}

Users 是另一个结构体。

然后,当我尝试在 Users 切片中添加一些新的 Users 值时,如下所示:

snapshots["test"].Users = append(snapshots["test"].Users, user)

我一直收到这个错误:

cannot assign to struct field snapshots["test"].Users in map

还在这里 https://github.com/golang/go/issues/3117 尝试了解决方法,就像这样:

tmp := snapshots["test"].Users
tmp = append(tmp, user)
snapshots["test"].Users = tmp

但没有运气,仍然是完全相同的错误。

并且还尝试用指针声明地图,所以: snapshots := make(map[string] *Snapshot, 1) ,仍然没有运气。

  • @keno,感谢您的回复,终于找到了为什么我已经使用指针后仍然无法工作的原因,那是因为我做了 snapshots := make(map[string] Snapshot, 1) ,然后我认为 len(snapshots) 会是1,后来我用一个for循环初始化了地图,它使用了 len(snapshots) 的值,....所以这意味着初始化过程永远不会运行....然后在我使用指针之后,我得到了这个错误:@ 987654333@

【解决方案1】:

对于那些寻找更简单示例的人:

这是错误的:

type myStruct struct{
   Field int
}

func main() {
   myMap := map[string]myStruct{
        "key":{
            Field: 1,
        },
   }

   myMap["key"].Field = 5
}

因为 myMap["key"] 不是“可寻址的”。

这是正确的:

type myStruct struct{
   Field int
}

func main(){
   myMap := map[string]myStruct{
       "key":{
           Field: 1,
       },
   }

   // First we get a "copy" of the entry
   if entry, ok := myMap["key"]; ok {

       // Then we modify the copy
       entry.Field = 5
    
       // Then we reassign map entry
       myMap["key"] = entry
   }

   // Now "key".Field is 5
   fmt.Println(myMap) // Prints map[key:{5}]
}

Here 你有一个工作示例。

  • 对于任何想进一步了解这一点的人来说, this 似乎是对可寻址性的讨论——尽管它似乎主要关注指针,并没有解释 为什么 这个选择是在 Go 语言中做出的(即为什么该语言不编译源代码“分配给数组中的结构域”以“创建结构中的临时变量-an-array,然后分配给它的一个字段“)。如果有经验的 Gopher 可以解释这个选择的理由,我很想理解它!