bitly / go-simplejson

a Go package to interact with arbitrary JSON
MIT License
3.76k stars 498 forks source link

Why the app panic? #78

Open netjune opened 5 years ago

netjune commented 5 years ago
package main

import (
    "fmt"
    js "github.com/bitly/go-simplejson"
)

func main() {
    child := js.New()
    child.Set("foo", "foo")
    child.Set("bar", "bar")

    parent := js.New()
    parent.Set("child_1", child)

    tmp_json := parent.Get("child_1")

    ss, _ := tmp_json.EncodePretty()
    fmt.Printf("==== ss: %s\n", ss)

    s1,err := tmp_json.Get("foo").String()
    if err != nil {
        panic(0)
    }
    fmt.Printf("=== s1: %s\n", s1)
}
phanirithvij commented 3 years ago

It is kind of a bug in the library, which people might expect to work out of the box. But it is a missing feature. You can take a look at how Set() and Get() are implemented to know why it's not working.

It is because the tmp_json is of type &Json{data:&Json{}} when it is supposed to be just &Json{}. EncodePretty works because the standard json library uses reflect (and does it correctly).

Two ways you can fix this in your code. (Workarounds)

  1. By using parent.Set("child_1", child.Interface()) instead of parent.Set("child_1", child).
  2. Or By using tmp_json.Interface().Get("foo").String()

i.e.

package main

import (
    "fmt"

    js "github.com/bitly/go-simplejson"
)

func main() {
    child := js.New()
    child.Set("bar", "bar")
    child.Set("foo", "foo")

    parent := js.New()

    // This
    parent.Set("child_interface", child.Interface())
    tmp_intf := parent.Get("child_interface")
    s1, err := tmp_intf.Get("foo").String()
    if err != nil {
        panic(err)
    }
    fmt.Printf("s1: %s\n", s1)

    // Or this
    parent.Set("child_json", child)
    tmp_json := parent.Get("child_json")
    s2, err := tmp_json.Interface().(*js.Json).Get("foo").String()
    if err != nil {
        panic(err)
    }
    fmt.Printf("s2: %s\n", s2)
}