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/秒的解组之间的区别。所以这几乎肯定不会成为你的瓶颈。 :)
我有一个相当大的嵌套 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/秒的解组之间的区别。所以这几乎肯定不会成为你的瓶颈。 :)