Friday, September 8, 2017

cannot assign to struct field in map error

cannot assign to struct field in map error

data["p1"] 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 the map implementation would get exposed.

So, instead, data["p1"] is a slightly different thing called a "map index expression" in the spec; if you search the spec for the phrase "index expression" you'll see you can do certain things with them, like read them, assign to them, and use them in increment/decrement expressions (for numeric types). But you can't do everything. They could have chosen to implement more special cases than they did, but I'm guessing they didn't just to keep things simple.

Issue code:

package main

import (
        "fmt"
)

type Person struct {
        Name string
}

func main() {
        data := map[string]Person{
                "p1": Person{},
        }

        data["p1"].Name = "Jun"

        fmt.Printf("%v\n", data)
}

Solution:

The solution is to make the map value a regular old pointer.

package main

import (
        "encoding/json"
        "fmt"
)

type Person struct {
        Name string
}

func main() {
        data := map[string]*Person{
                "p1": &Person{},
        }

        (*data["p1"]).Name = "Jun" // Or simply data["p1"].Name = "Jun"

        dataJSON, _ := json.MarshalIndent(data, "", "  ")
        fmt.Printf("%s\n", dataJSON)
}

Reference:

https://stackoverflow.com/questions/32751537/why-do-i-get-a-cannot-assign-error-when-setting-value-to-a-struct-as-a-value-i

No comments: