我尝试将node.js代码转换为golang代码。
这是我的示例JSON。
{
"result": {
"birthInfo": {
"birthYmd": "2018-07-25",
"cattleNo": "cow001",
"docType": "registerBirth",
"lsTypeNm": "redbull",
"monthDiff": "2018-07",
"nationNm": "japan",
"regType": "directly",
"regYmd": "2018-07-25",
"sexNm": "farm001"
},
"breed": {
"dead": {
"deadCd": "deadcd20180725",
"deadYmd": "2018-07-25",
"docType": "reportDeCattle"
},
"earTag": {
"docType": "reattachEartag",
"flatEartagNo": "eartag206015",
"rfidNo": "rfid234234"
}
}
}
}
使用node.js时,很容易获得或访问json数据。
let cowbytes = await stub.getState("cow001");
var cowInfo = JSON.parse(cowbytes);
var eartag = {
docType: 'reattachEartag',
flatEartagNo: "eartag206015",
rfidNo: "rfid234234",
};
if (cowInfo.breed) {
cowInfo.breed['earTag'] = eartag;
} else {
cowInfo.breed = {
earTag: eartag
};
}
await stub.putState(args[0], Buffer.from(JSON.stringify(cowInfo)));
这是我对node.js代码进行基准测试的golang代码。
cowbytes, _: = APIstub.GetState("cow001")
if cowbytes == nil {
return shim.Error("Incorrect value. No cattle Info..")
}
var cowInfo map[string] interface {}
json.Unmarshal(cowbytes, & cowInfo)
eartag: = make(map[string] interface {})
eartag["docType"] = "reattachEartag"
eartag["flatEartagNo"] = string("eartag206015")
eartag["rfidNo"] = string("rfid234234")
_, exists: = cowInfo["breed"]
if exists {
inputJSON,
err: = json.Marshal(cowInfo["breed"])
fmt.Println(err)
out: = map[string] interface {} {}
json.Unmarshal([] byte(inputJSON), & out)
out["earTag"] = struct {
EarTag map[string] interface {}
`json:"earTag"`
} {
eartag,
}
cowInfo["breed"] = out
}
else {
cowInfo["breed"] = struct {
EarTag map[string] interface {}
`json:"earTag"`
} {
eartag,
}
}
cattleAsBytes, _: = json.Marshal(cowInfo)
APIstub.PutState(string("cow001"), cattleAsBytes)
尽管我的golang文件可以正常工作,但我认为这不仅很难编写代码,而且性能也很差(重复的元组和非元组)。
如何在Golang中轻松控制JSON类型。
有人有主意吗?
答案 0 :(得分:4)
通常必须在性能和简单性之间进行选择。
如果需要性能,则可以使用结构对JSON输入进行建模,然后可以在结构上使用selectors轻松获取/设置不同的部分,并且还可以免费获得Go的类型安全性。注意:有些库和在线服务会根据输入的JSON文本(例如https://mholt.github.io/json-to-go/)自动生成Go结构。
如果您选择简单,则可以使用允许轻松操纵“动态”对象(例如地图和切片)的第三方库。
其中一个是github.com/icza/dyno
(披露:我是作者)。
使用dyno
,该解决方案的简单性接近JavaScript。由于dyno
在地图和切片上运行,因此对于某些任务可能会比较慢,但是对于您所要解决的简单任务,它可能甚至更快,因为它不使用反射(仅使用类型断言和类型切换)
比方说,标识符src
保存您输入的JSON文本(可以是常量或变量),那么等效于您的Go代码为:
var cowInfo interface{}
if err := json.Unmarshal([]byte(src), &cowInfo); err != nil {
panic(err)
}
eartag := map[string]string{
"docType": "reattachEartag",
"flatEartagNo": "eartag206015",
"rfidNo": "rfid234234",
}
if breed, err := dyno.Get(cowInfo, "result", "breed"); err == nil {
dyno.Set(breed, eartag, "earTag")
} else {
dyno.Set(cowInfo, map[string]interface{}{"earTag": eartag}, "result", "breed")
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
if err := enc.Encode(cowInfo); err != nil {
panic(err)
}
上面的代码解组输入的JSON,执行处理/修改,最后将结果编组到您的控制台上。
这是完整的应用程序:Go Playground。注意:您不能在Go Playground上运行它,因为它会导入github.com/icza/dyno
(并且不允许在其中导入3rd lib),您必须在本地运行(获取dyno
之后)。 / p>
答案 1 :(得分:0)
如果您的json结构是静态的,我建议定义适当的类型,例如:
type Result struct {
BirthInfo struct {
birthYmd string `json:"birthYmd"`
// other fields go here
} `json:"birthInfo"
// ...
} `json:"result"`
然后解析一次并使用:
cowInfo.BirthInfo.CattleId