Aleksandr Makov
Aleksandr Makov

Reputation: 2938

Golang: how to cast []string to a typed struct?

With json objects it's simple:

type MyObj struct {
    Prop1   int      `json:"prop1"`
    Prop2   []string `json:"prop2"`
}

How would I cast simple []string slice against MyObj? I know I could iterate over slice and manually assign each property by respective index, but maybe there's more optimal way, considering that Prop1 references at 0 index of the slice, and Prop2 - 1.

EDIT1:

My actual JSON string looks like [100, 200]. So MyObj.Prop1 would get filled with 100, and MyObj.Prop2 with 200 respectively.

Thank you.

Upvotes: 0

Views: 3039

Answers (2)

abhink
abhink

Reputation: 9116

You'll need a custom json.Umnarshaller:

type MyObj struct {
    Prop1   int      `json:"prop1"`
    Prop2   int      `json:"prop2"`
}

func (a *MyObj) UnmarshalJSON(b []byte) error {
    s := []string{}

    if err := json.Unmarshal(b, &s); err != nil {
        return err
    }

    l := len(s)

    // Check slice bounds and errors!!
    a.Prop1, _ = strconv.Atoi(s[0])
    a.Prop2, _ = strconv.Atoi(s[l-1])

    return nil
}

Example: https://play.golang.org/p/fVobgtrqNw

Upvotes: 3

lloiacono
lloiacono

Reputation: 5032

Given that you have your json as a string in a variable (yourString) then you can Unmarshall that into your []MyObj

yourString := `{"prop1":"100","prop2":"200"}`
var myObj MyObj
err := json.Unmarshal([]byte(yourString), &myObj)
if err == nil {
    fmt.Printf("%+v\n", myObj)
} else {
    fmt.Println(err)
    fmt.Printf("%+v\n", myObj)
}

Alternatively you can do this using json.decode:

yourString := `{"a" : ["prop1":100,"prop2":["200"]}`
var myObj MyObj
err := json.NewDecoder(strings.NewReader(yourString)).Decode(&myObj)
if err != nil {
    fmt.Println(err)
    return
}
fmt.Println(myObj.Prop1)
fmt.Println(myObj.Prop2)

Update

According to the MyObj you defined, your json should look like this: {"prop1":100,"prop2":["200"]}. Since prop1 is an int, and prop2 is a []string I think you either need to change your struct or change your json.

For instance you could define your MyObj like this:

type MyObj struct {
    Prop1   int      `json:"prop1"`
    Prop2   string   `json:"prop2"`
}

To match a json object like this:

{"prop1":100,"prop2":"200"}

If you want to keep MyObj as it is then your json should look like this:

{"prop1":100,"prop2":["200"]}

Check in the go playground: https://play.golang.org/p/yMpeBbjhkt

Upvotes: 2

Related Questions