序列化对象将使用 encoding/json 中的 Marshal 函数。golang
函数原型为:func Marshal(v interface{}) ([]byte, error)
json
如下是官网给出的例子:函数
package main import ( "encoding/json" "fmt" "os" ) func main() { type ColorGroup struct { ID int Name string Colors []string } group := ColorGroup{ ID: 1, Name: "Reds", Colors: []string{"Crimson", "Red", "Ruby", "Maroon"}, } b, err := json.Marshal(group) if err != nil { fmt.Println("error:", err) } os.Stdout.Write(b) }
须要注意的是:json.Marshal返回了[]byte类型,一般状况下,须要将其转换为string类型使用。指针
反序列化对象将使用 encoding/json 中的 Unmarshal 函数。code
函数原型为:func Unmarshal(data []byte, v interface{}) error
对象
如下是官网给出的例子:递归
package main import ( "encoding/json" "fmt" ) func main() { var jsonBlob = []byte(`[ {"Name": "Platypus", "Order": "Monotremata"}, {"Name": "Quoll", "Order": "Dasyuromorphia"} ]`) type Animal struct { Name string Order string } var animals []Animal err := json.Unmarshal(jsonBlob, &animals) if err != nil { fmt.Println("error:", err) } fmt.Printf("%+v", animals) }
在反序列化时,有可能不知道Json数据的具体类型,那应该怎么办呢?rem
其实,观察json.Unmarshal的函数原型能够看到,其第二个参数是一个interface。get
事实上,你能够传入一个interface对象的指针,反序列化函数依然会填充这个对象。而且这个对象能够被转换成为map[string]interface{}
这样的类型或者[]interface{}
这样的类型,这取决于Json的内容。原型
因而,咱们便有了在不知道Json数据具体类型的状况下,解析Json内容的方法。
代码以下:
package main import ( "encoding/json" "fmt" ) func main() { var jsonBlob = []byte(`[ {"Name": "Platypus", "Order": "Monotremata"}, {"Name": "Quoll", "Order": "Dasyuromorphia"} ]`) var jsonObject interface{} err := json.Unmarshal(jsonBlob, &jsonObject) if err != nil { fmt.Println("error:", err) } animals := jsonObject.([]interface{}) for i := 0; i < len(animals); i++ { animalObject := animals[i] animalMap := animalObject.(map[string]interface{}) fmt.Println(animalMap["Name"]) fmt.Println(animalMap["Order"]) } }
如上,咱们能够将反序列化出的对象,递归地进行类型转换,转换为[]interface{}
或者map[string]interface{}
,这样就能一层层地解析Json的内容了。
固然,以上只是举例,证实能够经过一些手段解析未知结构的Json。为了正确解析未知结构的Json内容,你可能须要为解析过程添加一些判断,如解析出的对象的类型须要二选一,又如解析出的map类型中键的存在性等等。