Heim >Backend-Entwicklung >Golang >Bringen Sie Ihnen bei, wie Sie Json in Go verwenden

Bringen Sie Ihnen bei, wie Sie Json in Go verwenden

藏色散人
藏色散人nach vorne
2021-12-28 15:44:211607Durchsuche

Dieser Artikel wurde von golangTutorial-Kolumne geschrieben, um die Verwendung von Json in der Go-Sprache vorzustellen. Ich hoffe, dass er Freunden in Not hilfreich sein wird!

Encode

Encoden Sie ein Objekt in JSON-Daten, akzeptieren Sie ein interface{}-Objekt, geben Sie []byte zurück und error: JSON数据,接受一个interface{}对象,返回[]byteerror

func Marshal(v interface{}) ([]byte, error)

Marshal函数将会递归遍历整个对象,依次按成员类型对这个对象进行编码,类型转换规则如下:

  • bool类型 转换为JSONBoolean

  • 整数,浮点数等数值类型 转换为JSONNumber

  • string 转换为JSON的字符串(带””引号)

  • struct 转换为JSONObject,再根据各个成员的类型递归打包

  • 数组或切片 转换为JSONArray

  • []byte 会先进行base64编码然后转换为JSON字符串

  • map转换为JSONObjectkey必须是string

  • interface{} 按照内部的实际类型进行转换

  • nil 转为JSONnull

  • channel,func等类型 会返回UnsupportedTypeError

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) Output: {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}

Decode

JSON数据解码

func Unmarshal(data []byte, v interface{}) error

类型转换规则和上面的规则类似

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) Output: [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]

结构体

结构体必须是大写字母开头的成员才会被JSON处理到,小写字母开头的成员不会有影响。

Mashal时,结构体的成员变量名将会直接作为JSON Objectkey打包成JSONUnmashal时,会自动匹配对应的变量名进行赋值,大小写不敏感。

Unmarshal时,如果JSON中有多余的字段,会被直接抛弃掉;如果JSON缺少某个字段,则直接忽略不对结构体中变量赋值,不会报错。

type Message struct { 
 Name string 
 Body string 
 Time int64 
 inner string 
} var m = Message{ 
 Name: "Alice", 
 Body: "Hello", 
 Time: 1294706395881547000, 
 inner: "ok", } b := []byte(`{"nAmE":"Bob","Food":"Pickle", "inner":"changed"}`) err := json.Unmarshal(b, &m) if err != nil { 
 fmt.Printf(err.Error()) 
 return} fmt.Printf("%v", m) Output: {Bob Hello 1294706395881547000 ok}

StructTag

如果希望手动配置结构体的成员和JSON字段的对应关系,可以在定义结构体的时候给成员打标签:

使用omitempty熟悉,如果该字段为nil或0值(数字0,字符串””,空数组[]等),则打包的JSON结果不会有这个字段。

type Message struct { 
 Name string `json:"msg_name"`  // 对应JSON的msg_name 
 Body string `json:"body,omitempty"` // 如果为空置则忽略字段 
 Time int64 `json:"-"`    // 直接忽略字段 } var m = Message{ 
 Name: "Alice", 
 Body: "", 
 Time: 1294706395881547000, } data, err := json.Marshal(m) if err != nil { 
 fmt.Printf(err.Error()) 
 return} fmt.Println(string(data)) Output: {"msg_name":"Alice"}

更灵活地使用JSON

使用json.RawMessage

json.RawMessage其实就是[]byte类型的重定义。可以进行强制类型转换。

现在有这么一种场景,结构体中的其中一个字段的格式是未知的:

type Command struct { 
 ID int 
 Cmd string 
 Args *json.RawMessage 
}

使用json.RawMessage的话,Args字段在Unmarshal时不会被解析,直接将字节数据赋值给Args。我们可以能先解包第一层的JSON数据,然后根据Cmd的值,再确定Args的具体类型进行第二次Unmarshal

这里要注意的是,一定要使用指针类型*json.RawMessage,否则在Args会被认为是[]byte类型,在打包时会被打包成base64编码的字符串。

使用interface{}

interface{}类型在Unmarshal时,会自动将JSON转换为对应的数据类型:

JSON的boolean 转换为boolJSON的数值 转换为float64JSON的字符串 转换为stringJSON的Array 转换为[]interface{}JSON的Object 转换为map[string]interface{}JSON的null 转换为nil

需要注意的有两个。一个是所有的JSON数值自动转换为float64类型,使用时需要再手动转换为需要的intint64等类型。第二个是JSONobject自动转换为map[string]interface{}类型,访问时直接用JSON ``Object的字段名作为key进行访问。再不知道JSON数据的格式时,可以使用interface{}

type Marshaler interface { 
 MarshalJSON() ([]byte, error) } type Unmarshaler interface { 
 UnmarshalJSON([]byte) error 
}
Die Funktion Marshal durchläuft das gesamte Objekt rekursiv und codiert das Objekt nacheinander nach Mitgliedstyp. Die Typkonvertierungsregeln lauten wie folgt: 🎜
    🎜bool-Typ wird in JSONs Boolean🎜
  • 🎜Ganzzahl, Gleitkommazahl und andere numerische Werte konvertiert Typen werden in JSONs Number konvertiert. 🎜
  • 🎜string wird in einen String von JSON (mit „“-Anführungszeichen) 🎜
  • 🎜struct wird in Object von JSON konvertiert und dann rekursiv entsprechend dem Typ jedes Mitglieds gepackt🎜
  • 🎜Das Array oder Slice, das in JSONs Array🎜
  • 🎜 konvertiert wurde []byte wird zuerst mit der base64-Codierung verarbeitet und dann in den JSON-String 🎜
  • 🎜map in <code>JSONs >Object konvertiert, key muss string🎜
  • 🎜interface{} entsprechend dem tatsächlichen internen Typ Konvertieren Sie 🎜
  • 🎜nil in JSONs null🎜
  • 🎜channel , func und andere Typen geben UnsupportedTypeError🎜
  • rrreee🎜🎜🎜🎜Decode🎜🎜🎜will JSON code>Data decoding🎜rrreee🎜Die Typkonvertierungsregeln ähneln den oben genannten Regeln🎜🎜🎜🎜Struktur🎜🎜🎜Die Struktur muss sein Ein Mitglied, das mit einem Großbuchstaben beginnt, soll von <code>JSON verarbeitet werden. Kleingeschriebene Mitglieder, die mit einem Buchstaben beginnen, haben keine Auswirkung. 🎜🎜Mashal, der Mitgliedsvariablenname der Struktur wird direkt in als <code>Schlüssel von JSON Object >JSON; Unmashal gleicht automatisch den entsprechenden Variablennamen für die Zuweisung ab und unterscheidet nicht zwischen Groß- und Kleinschreibung. 🎜🎜Wenn bei Unmarshal zusätzliche Felder in JSON vorhanden sind, werden diese direkt verworfen; wenn in JSON ein Feld fehlt, wird dies der Fall sein Wenn Sie den Variablen in der Struktur keine Werte zuweisen, wird kein Fehler gemeldet. 🎜rrreee🎜🎜🎜🎜StructTag🎜🎜🎜Wenn Sie die Korrespondenz zwischen den Mitgliedern der Struktur und dem Feld JSON manuell konfigurieren möchten, können Sie die Mitglieder beim Definieren der Struktur markieren: 🎜🎜Verwenden Sie omitempty ist bekannt. Wenn das Feld nil oder einen Wert von 0 hat (Zahl 0, Zeichenfolge "", leeres Array [] usw.), wird das gepackte JSON Code> Ergebnis Es wird kein solches Feld geben. 🎜rrreee🎜Verwenden Sie <code>JSON flexibler🎜🎜🎜🎜🎜Verwenden Sie json.RawMessage🎜🎜🎜json.RawMessage ist eigentlich der Typ []byte Neudefinition. Casting ist möglich. 🎜🎜Jetzt gibt es ein Szenario, in dem das Format eines der Felder in der Struktur unbekannt ist: 🎜rrreee🎜Wenn Sie json.RawMessage verwenden, befindet sich das Feld Args in Unmarshal wird nicht geparst und die Bytedaten werden direkt Args zugewiesen. Wir können zuerst die erste Ebene der JSON-Daten entpacken und dann zum zweiten Mal den spezifischen Typ von Args basierend auf dem Wert von Cmd bestimmen . Unmarshal. 🎜🎜Hier ist zu beachten, dass Sie den Zeigertyp *json.RawMessage verwenden müssen, da sonst die Args als []bytebetrachtet werden > Typ wird beim Packen in eine base64-codierte Zeichenfolge gepackt. 🎜🎜🎜🎜🎜Mit der Schnittstelle{}🎜🎜🎜interface{} wird JSON automatisch in die entsprechenden Daten konvertiert, wenn Unmarshal Typ: 🎜 rrreee🎜Es gibt zwei Dinge zu beachten. Zum einen werden alle JSON-Werte automatisch in den Typ float64 konvertiert. Bei Verwendung müssen sie manuell in den erforderlichen int konvertiert werden. int64 code> und andere Typen. Das zweite ist, dass das <code>object von JSON automatisch in den Typ map[string]interface{} konvertiert wird und direkt mit JSON „Auf den Feldnamen des Objekts wird als <code>Schlüssel zugegriffen. Wenn Sie das Format von JSON-Daten nicht kennen, können Sie interface{} verwenden. 🎜

    自定义类型

    如果希望自己定义对象的打包解包方式,可以实现以下的接口:

    type Marshaler interface { 
     MarshalJSON() ([]byte, error) } type Unmarshaler interface { 
     UnmarshalJSON([]byte) error 
    }

    实现该接口的对象需要将自己的数据打包和解包。如果实现了该接口,json在打包解包时则会调用自定义的方法,不再对该对象进行其他处理。                                                          

Das obige ist der detaillierte Inhalt vonBringen Sie Ihnen bei, wie Sie Json in Go verwenden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:learnku.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen