Go to json.Decode a json object to an empty interface 是不好的做法吗?

Is it bad practice in Go to json.Decode a json object to an empty interface?

我有一个相当大的嵌套 JSON 对象,我想对其进行解码。我可以将其解码为定义明确的嵌套结构,但我看到的另一种解决方案是将其解码为空接口。

从功能上讲,这工作正常。但是我想知道当我从 JSON 解码对象时以及稍后将其编组为 JSON.

时,我是否会在幕后招致性能损失(反映)

想法?提前致谢。

代码:

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

对比

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:"-"

还有可能更多。

这完全取决于您打算如何处理未编组的数据。

如果您的 json 数据中有嵌套对象/数组,那么您最终会得到嵌套接口。这意味着您需要将接口显式转换为正确的类型才能访问它们的数据。在这种情况下,您最好使用第二个示例中的结构,因为您可以像 myData.Items[0].CustomizationState.Areas[0].Height 中那样更轻松地访问数据。使用嵌套接口转换将是一件痛苦的事情。

另一方面,如果您只是输出此数据,例如作为对 web 服务调用的响应,那么您不需要知道结构,只需将其吐出即可。

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

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

这里 link 显示了两种方法之间访问难易程度的差异。 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/秒的解组之间的区别。所以这几乎肯定不会成为你的瓶颈。 :)