无法从映射中分配给结构体成员

huangapple go评论87阅读模式
英文:

Can not assign to a struct member from map

问题

类型t_struct定义了一个包含player和id两个字段的结构体。在main函数中,定义了两个map变量dataA和dataB,分别用于存储t_struct类型和*t_struct类型的数据。

首先,创建了一个t_struct类型的变量playerA,并给其player字段赋值为"tom",id字段赋值为1。然后将playerA存储到dataA中的键"classA"对应的值中。接着,尝试修改dataA["classA"]的id字段为2,但出现了错误,原因是不能直接对map中的字段进行赋值操作。

接下来,使用new函数创建了一个*t_struct类型的变量playerB,并将其存储到dataB中的键"classB"对应的值中。然后,通过dataB["classB"]来修改playerB的player字段为"rick",以及id字段为3。

所以,只有将结构体的指针存储到map中,才能修改其成员的值。

英文:

Code:

type t_struct struct {
    player string
    id     int
}

func main() {
    dataA := make(map[string]t_struct)
    dataB := make(map[string]*t_struct)

    var playerA t_struct
    playerA.player = "tom"
    playerA.id = 1
    dataA["classA"] = playerA
    dataA["classA"].id = 2 // ERROR, why?
    
    playerB := new(t_struct)
    dataB["classB"] = playerB
    dataB["classB"].player = "rick"
    dataB["classB"].id = 3
}

And got error:

> cannot assign to dataA["classA"].id

I wonder why dataA["classA"].id = 2 not worked but dataB["classB"].id = 3 did? Is it the only way to save struct pointer into map if you want to modify member value of it?

答案1

得分: 7

表达式dataA["classA"]的类型是t_struct。这意味着

dataA["classA"].id = 2

等同于

t_struct{"some player", 42}.id = 2

Playground

换句话说,结构体值没有“家”,改变其字段是无法持久化的。由于唯一可能性是程序员的错误,编译器会标记一个错误。

另一方面:

dataB["classB"]

的类型是*t_struct。然后

dataB["classB"].id = 3

等同于

(*t_struct)(somePointer).id = 3

也就是说,这个_lvalue_有一个“家”。它指向指针所指向的位置。对字段的更改将在那里“记录”,因此它是一个有效的Go操作(对由指针引用的结构体字段的简单赋值)。

英文:

The expression dataA["classA"] if of type t_struct. That means that

dataA["classA"].id = 2

is equvalent to e.g.

t_struct{"some player", 42}.id = 2

Playground

IOW, the struct value has no "home" and changing its field cannot be persisted. As the only possibility is a programmer's mistake, the compiler flags an error.

OTOH:

dataB["classB"]

has type *t_struct. Then

dataB["classB"].id = 3

is equivalent to

(*t_struct)(somePointer).id = 3

I.e., this lvalue has a "home". It's where the pointer points to. The change to the field will be "recorded" there and it is thus a valid Go operation (simple assignment to a struct field where the struct is referenced by a pointer).

huangapple
  • 本文由 发表于 2013年4月17日 19:40:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/16059038.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定