Goのjson解析:MarshalとUnmarshal
3366 ワード
Json Marshal:データをjson文字列に符号化する
簡単な例を見てみましょう
結果:
結果から、は、エクスポート可能なメンバー(変数の頭文字が大文字)であれば、jsonに変換できます.メンバー変数sexはエクスポートできないため、jsonに変換できません. 変数にjsonラベルが付けられている場合、Nameの隣の boolタイプもjsonのvalue値に直接変換できます.Channel,complexおよび関数はjson文字列を符号化できない.もちろん、ループのデータ構造もだめで、marshalがデッドサイクルに陥ることになります. ポインタ変数は、符号化時にcla変数のような値に自動的に変換されます.(もちろん、ポインタを渡さず、Stu structのメンバーClassをClass structタイプに変えれば、効果もそっくりです.ただしポインタが速く、メモリスペースを節約できます.) 最後に、jsonが文字列に符号化された後、純粋な文字列であることを強調した.
上のメンバー変数はすべて既知のタイプであり、stringタイプのNameがstringタイプのデータを割り当てることができるなど、指定したタイプしか受信できません.しかし,汎用性のために,あるいはコードを簡潔にするために,種々のタイプのデータを受け入れ,json符号化を行うタイプが望ましい場合がある.これはinterface{}タイプを使用します.
Json Unmarshal:json文字列を対応するデータ構造に復号
上記の例を復号化します
結果:
まとめ: json文字列解析では、解析後のデータを受信する「受信体」が必要であり、Unmarshalでは受信体がポインタを渡さなければならない.そうでなければ解析は誤りを報告しないが,データは受信体に付与できない.ここではStuRead{}受信を使用します. 解析の場合、受信体は自己定義することができる.json列のkeyは、受信体で一致するアイテムを自動的に探して付与します.一致ルールは、(1)keyと同じjsonタグを検索し、検索するとそのタグに対応する変数(Nameなど)が割り当てられます.(2)jsonタグがない場合は,Ageのように変数名がkeyと同じ変数を上から順に検索する.あるいは変数名は大文字と小文字のkeyと同じ変数を無視します.HIgh、Classのように.最初のマッチングは値を割り当て、後でマッチングがあっても無視します.(この変数は、書き出し可能、すなわち頭文字大文字である必要があることを前提とします). 導出不可能な変数は解析できない(例えばsex変数、json列にkeyがsexのk-vがあるが、解析後もその値はnil、すなわち空の値) .受信体にjson列で一致しない項目が存在する場合、解析は自動的にその項目を無視し、その項目は元の値を保持する.変数Testのように、空の値nilを保持します.
変換元:https://cloud.tencent.com/developer/article/1515861
簡単な例を見てみましょう
type Stu struct {
Name string `json:"name"`
Age int
HIgh bool
sex string
Class *Class `json:"class"`
}
type Class struct {
Name string
Grade int
}
func main() {
// , json
stu := Stu{
Name: " ",
Age: 18,
HIgh: true,
sex: " ",
}
//
cla := new(Class)
cla.Name = "1 "
cla.Grade = 3
stu.Class=cla
//Marshal err!=nil
jsonStu, err := json.Marshal(stu)
if err != nil {
fmt.Println(" json ")
}
//jsonStu []byte , string
fmt.Println(string(jsonStu))
}
結果:
{"name":" ","Age":18,"HIgh":true,"class":{"Name":"1 ","Grade":3}}
結果から、
json:"name"
のように、変換されたjson keyはそのラベル「name」を使用し、そうでなければ変数名をkey、例えば「Age」、「HIgh」とします.上のメンバー変数はすべて既知のタイプであり、stringタイプのNameがstringタイプのデータを割り当てることができるなど、指定したタイプしか受信できません.しかし,汎用性のために,あるいはコードを簡潔にするために,種々のタイプのデータを受け入れ,json符号化を行うタイプが望ましい場合がある.これはinterface{}タイプを使用します.
Json Unmarshal:json文字列を対応するデータ構造に復号
上記の例を復号化します
type StuRead struct {
Name interface{} `json:"name"`
Age interface{}
HIgh interface{}
sex interface{}
Class interface{} `json:"class"`
Test interface{}
}
type Class struct {
Name string
Grade int
}
func main() {
//json " , \ ,
//json , key , sex
data:="{\"name\":\" \",\"Age\":18,\"high\":true,\"sex\":\" \",\"CLASS\":{\"naME\":\"1 \",\"GradE\":3}}"
str:=[]byte(data)
//1.Unmarshal json , json 。
// , , stu StuRead{}
//2. stu:=new(StuRead), stu
stu:=StuRead{}
err:=json.Unmarshal(str,&stu)
// , json , " , } 。
if err!=nil{
fmt.Println(err)
}
fmt.Println(stu)
}
結果:
{ 18 true map[naME:1 GradE:3] }
まとめ:
変換元:https://cloud.tencent.com/developer/article/1515861