转到json是不好的做法。将json对象解码为空接口?

时间:2015-02-18 17:57:14

标签: json encoding go

我想要解码一个相当大的嵌套JSON对象。我可以将其解码为定义良好的嵌套结构,但我已经看到的另一种解决方案是将其解码为空接口。

从功能上讲,这很好用。但是我想知道当我从JSON解码对象时,以及当我稍后将其编组为JSON时,我是否会在幕后产生性能损失(反映)。

思考?提前谢谢。

代码:

CustomizationData    interface{} `json:"customizationData" datastore:"-"`

VS

CustomizationData    struct {
    Items []struct {
        ID     string `json:"id"`
        Images []struct {
            CustomizationState struct {
                Areas []struct {
                    Height float64 `json:"height"`
                    ID     string  `json:"id"`
                    Left   float64 `json:"left"`
                    Parent struct {
                        Height float64 `json:"height"`
                        Left   float64 `json:"left"`
                        Top    float64 `json:"top"`
                        Width  float64 `json:"width"`
                    } `json:"parent"`
                    Rotation float64 `json:"rotation"`
                    Text     string  `json:"text"`
                    Top      float64 `json:"top"`
                    URL      string  `json:"url"`
                    Width    float64 `json:"width"`
                } `json:"areas"`
                BackgroundColor string  `json:"backgroundColor"`
                IsUserSet       bool    `json:"isUserSet"`
                Orientation     float64 `json:"orientation"`
            } `json:"customizationState"`
            SpaceId string `json:"spaceId"`
        } `json:"images"`
        ProductId    float64 `json:"productId"`
        Quantity     float64 `json:"quantity"`
        Sku          string  `json:"sku"`
        TemplateName string  `json:"templateName"`
    } `json:"items"`
    ShippingAddress struct {
        City        string `json:"city"`
        CountryCode string `json:"countryCode"`
        Email       string `json:"email"`
        FirstName   string `json:"firstName"`
        LastName    string `json:"lastName"`
        Line1       string `json:"line1"`
        Phone       string `json:"phone"`
        PostalCode  string `json:"postalCode"`
        State       string `json:"state"`
    } `json:"shippingAddress"`
    TimeStamp string `json:"timeStamp"`
} `json:"customizationData" datastore:"-"

可能更多。

1 个答案:

答案 0 :(得分:3)

这完全取决于您打算如何处理Unmarshalled数据。

如果在json数据中嵌套了对象/数组,那么最终将使用嵌套接口。这意味着您需要将接口显式转换为正确的类型以访问其数据。在这种情况下,您最好在第二个示例中使用结构,因为您可以像myData.Items[0].CustomizationState.Areas[0].Height中那样更轻松地访问数据。使用嵌套接口转换这样做会很麻烦。

另一方面,如果您只是输出这些数据,例如作为对网络服务电话的回复,那么您不需要知道结构,只能将其吐出来。

就个人而言,我总是使用后者。

我假设您正在http://mervine.net/json2struct使用强大的服务将您的json转换为可用的Go结构。

这是一个显示两种方法之间访问容易程度差异的链接。 http://play.golang.org/p/OlJJPZcxT7

对于那些想要留在页面中的人:

var dataz = `{"foo": ["bar", "baz"], "boff": {"foo": "bar", "baz": "boff"}}`

type Dataz struct {
    Foo  []string `json:"foo"`
    Boff struct {
        Foo string `json:"foo"`
        Baz string `json:"baz"`
    } `json:"boff"`
}

func main() {
    // Method 1
    var d interface{}
    json.Unmarshal([]byte(dataz), &d)
    fmt.Println(d.(map[string]interface{})["foo"].([]interface{})[0])

    // Method 2
    var D Dataz
    json.Unmarshal([]byte(dataz), &D)
    fmt.Println(D.Foo[0])
}

修改
根据有关表现的评论进行编辑

幸运的是,我们可以使用内置的Go工具

进行测试
> go test -bench .
testing: warning: no tests to run
PASS
BenchmarkInterface    300000          6208 ns/op
BenchmarkStruct       500000          3622 ns/op
ok      parse   3.773s

处理276,000 /秒或161,000 /秒的解组之间的区别。所以这几乎肯定不是你的瓶颈。 :)