我正在尝试在Go中编写的REST API中解码传入的JSON。我正在使用decoder.Decode()
函数,我的问题是我需要对解码过程中应该使用哪个结构应用某些规则,因为有时JSON包含:
"type": {
"type" : "string",
"maxLength" : 30
},
有时候:
"type": {
"type" : "integer",
"max" : 30,
"min" : 10
},
我不知何故需要告诉Go“如果type.type是字符串,请使用此结构(type Type_String struct
),如果type.type是整数,请使用其他结构(type Type_Integer struct
)”。我不确定该怎么做。我想到的一个解决方案是创建一个具有所有可能属性的通用结构,在任何类型的对象上使用它,然后根据type
属性过滤属性,但这很脏。我想我也可以编写自己的解码器,但这看起来也有点奇怪。
我是Go的新手,我非常习惯JavaScript提供的自由。
答案 0 :(得分:1)
首先,如果“type”的字段取决于“type.type”,在我看来,最好将其移动一级。类似的东西:
...
"type" : "integer",
"intOptions": {
"max" : 30,
"min" : 10
},
....
然后你可以创建一个只有一个字段的结构:
type Type struct {
Type string
}
并执行以下操作:
myType := new(Type)
json.Unmarshal([]byte(yourJsonString), myType)
现在,根据myType的值,您可以使用不同的结构来解码您的json。
答案 1 :(得分:0)
您可以随时解码到此处提到的界面{}:How to access interface fields on json decode?
http://play.golang.org/p/3z8-unhsH4
package main
import (
"encoding/json"
"fmt"
)
var one string = `{"type": {"type": "string", "maxLength":30}}`
var two string = `{"type": {"type": "integer", "max":30, "min":10}}`
func f(data map[string]interface{}) {
t := data["type"]
typemap := t.(map[string]interface{})
t2 := typemap["type"].(string)
switch t2 {
case "string":
fmt.Println("maxlength:", typemap["maxLength"].(float64))
case "integer":
fmt.Println("max:", typemap["max"].(float64))
default:
panic("oh no!")
}
}
func main() {
var jsonR map[string]interface{}
err := json.Unmarshal([]byte(one), &jsonR)
if err != nil {
panic(err)
}
f(jsonR)
json.Unmarshal([]byte(two), &jsonR)
f(jsonR)
}
我们的想法是解组map [string] interface {},然后在访问值之前进行转换和比较。
在上面的代码中,f函数执行强制转换和比较。鉴于这个可怜的json,我使用了差的变量名t和t2来表示"类型"的json值。在不同的深度。一旦t2具有该值,switch语句就会使用" string"或者"整数"它的作用是打印maxLength或最大值。