为了存储结构的可扩展性,会在数据结构中加入一个扩展字段,大多时候会选择使用一个json字符串。但json中每个value都有自己的结构,比如字符串/struct/[]struct,解析的时候大致有两种思路:
- 整个json解析为一个map[string]interface{},需要对应的key时拿到value再次解析
- 针对当前的json结构,定义一个struct,直接解析为该机构
下面的例子是实现interface{}/[]interface{}与特定类型之间的转化,也是经常遇到的情形,demo如下:
interface{} to struct
package main
import (
"encoding/json"
"fmt"
)
func main() {
kv := KV{
Title: "hello world",
Content: "this is content",
}
//make a special to a common type, then we use the common type change to the special type
common := CommonType{kv}
byteData, _ := json.Marshal(common)
common2 := CommonType{}
json.Unmarshal(byteData, &common2)
receiveCustomer := conveert(common2.Data)
fmt.Println(receiveCustomer)
}
type KV struct {
Title string `json:"title"`
Content string `json:"content"`
}
type CommonType struct {
Data interface{} `json:"data"`
}
func conveert(data interface{}) KV {
kv := KV{}
bodyBytes, _ := json.Marshal(data)
json.Unmarshal(bodyBytes, &kv)
return kv
}
[]interface{} to struct
package main
import (
"encoding/json"
"fmt"
)
func main() {
jsonstr := "{\"data\":[{\"title\": \"title1\", \"content\": \"content1\"}, {\"title\": \"title2\", \"content\": \"content2\"}]}"
// we have a json string, the value is a list value, we need unmarshal the value to a kv list
res := make(map[string][]interface{})
json.Unmarshal([]byte(jsonstr), &res)
receiveCustomer := convert(res["data"])
fmt.Println(receiveCustomer)
}
type KV struct {
Title string `json:"title"`
Content string `json:"content"`
}
func convert(data interface{}) []KV {
kvs := []KV{}
bodyBytes, _ := json.Marshal(data)
json.Unmarshal(bodyBytes, &kvs)
return kvs
}