0
votes

My goals is to dynamically select struct type to unmarshal json to. If I use pointer to struct - it works fine and parses json to struct as expected, but If I use struct and then get pointer to it and do unmarshal, it unmarshals it to map[string]interface{} instead of struct.

What am I doing wrong?

https://play.golang.org/p/AkaCt_f69GV

package main

import (
    "fmt"
    "encoding/json"
)

type Person struct {
    Name string
}

var source = []byte(`{"Name":"Dan"}`)

func main() {
    parse1()
    parse2()
}

func parse1() {
    var value interface{}
    value = new(Person)

    json.Unmarshal(source, value)
    // {Dan}
    fmt.Println(*(value.(*Person)))
}

func parse2() {
    var value interface{}
    value = Person{}

    json.Unmarshal(source, &value)
    // map[Name:Dan]
    fmt.Println(value)
}
1

1 Answers

3
votes

In parse2, the decoder ignores the Person value because the value is not addressable. The decoder decodes to the interface{} value because it is addressable.

Fix the problem by passing an addressable Person to the function.

Use this code:

func parse2() {
    var value interface{}
    value = &Person{}  // add & on this line

    json.Unmarshal(source, &value)
    fmt.Println(value)
}

or this code:

func parse2() {
    var value interface{}
    value = &Person{}  // add & on this line

    json.Unmarshal(source, value) // remove & on this line
    fmt.Println(value)
}