Maison > développement back-end > Golang > Apprenez à utiliser Json dans Go

Apprenez à utiliser Json dans Go

藏色散人
Libérer: 2021-12-28 15:45:05
avant
1616 Les gens l'ont consulté

Cet article est écrit par la colonne tutorielle golang pour vous présenter comment utiliser Json en langage Go. J'espère qu'il sera utile aux amis dans le besoin !

Encode

Encoder un objet dans des données JSON, accepter un objet interface{}, renvoyer []octet et error : JSON数据,接受一个interface{}对象,返回[]byteerror

func Marshal(v interface{}) ([]byte, error)
Copier après la connexion

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"]}
Copier après la connexion

Decode

JSON数据解码

func Unmarshal(data []byte, v interface{}) error
Copier après la connexion

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

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}]
Copier après la connexion

结构体

结构体必须是大写字母开头的成员才会被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}
Copier après la connexion

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"}
Copier après la connexion

更灵活地使用JSON

使用json.RawMessage

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

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

type Command struct { 
 ID int 
 Cmd string 
 Args *json.RawMessage 
}
Copier après la connexion

使用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
Copier après la connexion

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

type Marshaler interface { 
 MarshalJSON() ([]byte, error) } type Unmarshaler interface { 
 UnmarshalJSON([]byte) error 
}
Copier après la connexion
Copier après la connexion
La fonction Marshal parcourra récursivement l'intégralité de l'objet et encodera l'objet à son tour par type de membre. Les règles de conversion de type sont les suivantes : 🎜
    🎜Le type bool est converti en booléen de <code>JSON🎜
  • 🎜Entier, virgule flottante et autres valeurs numériques les types sont convertis en JSON. Le Nombre🎜
  • 🎜string est converti en une chaîne de <code>JSON (avec "" guillemets) 🎜
  • 🎜struct est converti en Object de <code>JSON, puis récursivement emballé en fonction du type de chaque membre🎜
  • 🎜Le tableau ou la tranche converti en Array de <code>JSON🎜
  • 🎜 []byte sera traité en premier encodage base64 puis converti en chaîne JSON 🎜
  • 🎜map converti en <code> >Objet de <code>JSON, la clé doit être une chaîne🎜
  • 🎜interface{} selon le type interne réel Convertir 🎜
  • 🎜nil en de <code>JSON null🎜
  • 🎜channel , func et d'autres types renverront UnsupportedTypeError🎜
  • rrreee🎜🎜🎜🎜Decode🎜🎜🎜will JSON code>Décodage des données🎜rrreee🎜Les règles de conversion de type sont similaires aux règles ci-dessus🎜rrreee🎜🎜🎜🎜Structure🎜🎜🎜La structure doit être un membre commençant par une lettre majuscule sera traité par <code>JSON, les membres minuscules commençant par une lettre n'auront aucun effet. 🎜🎜Mashal, le nom de la variable membre de la structure sera directement empaqueté dans en tant que <code>clé de <code>JSON Object >JSON ; Unmashal correspondra automatiquement au nom de la variable correspondante pour l'affectation et n'est pas sensible à la casse. 🎜🎜Lors de Unmarshal, s'il y a des champs supplémentaires dans JSON, ils seront supprimés directement s'il manque un champ dans JSON, ce sera le cas ; ignoré directement. Si vous n'attribuez pas de valeurs aux variables de la structure, aucune erreur ne sera signalée. 🎜rrreee🎜🎜🎜🎜StructTag🎜🎜🎜Si vous souhaitez configurer manuellement la correspondance entre les membres de la structure et le champ JSON, vous pouvez taguer les membres lors de la définition de la structure : 🎜🎜Utilisez omitempty est familier, si le champ est nil ou 0 (numéro 0, chaîne "", tableau vide [], etc.), le JSON code> compressé code> résultat Il n'y aura pas de tel champ. 🎜rrreee🎜Utilisez <code>JSON de manière plus flexible🎜🎜🎜🎜🎜Utilisez json.RawMessage🎜🎜🎜json.RawMessage est en fait le type []byte redéfinition. Le casting est possible. 🎜🎜Il existe maintenant un scénario où le format d'un des champs de la structure est inconnu : 🎜rrreee🎜Si vous utilisez json.RawMessage, le champ Args est dans Unmarshal ne sera pas analysé et les données d'octets seront affectées directement à Args. Nous pouvons d'abord décompresser la première couche de données JSON, puis déterminer le type spécifique de Args en fonction de la valeur de Cmd pour la deuxième fois. . Démaréchal. 🎜🎜Il est à noter ici que vous devez utiliser le type de pointeur *json.RawMessage, sinon le Args sera considéré comme le []byte type , sera compressé dans une chaîne codée base64 lors de l'empaquetage. 🎜🎜🎜🎜🎜L'utilisation du type interface{}🎜🎜🎜interface{} convertira automatiquement JSON en données correspondantes lorsque Unmarshal tape : 🎜 rrreee🎜Il y a deux choses à noter. La première est que toutes les valeurs JSON sont automatiquement converties en type float64. Lorsqu'elles sont utilisées, elles doivent être converties manuellement en int requis. , int64 code> et d'autres types. La seconde est que l'<code>objet de <code>JSON est automatiquement converti en type map[string]interface{} et est directement accessible à l'aide de <code>JSON `` Le nom du champ de l'objet est accessible en tant que <code>clé. Lorsque vous ne connaissez pas le format des données JSON, vous pouvez utiliser interface{}. 🎜

    自定义类型

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

    type Marshaler interface { 
     MarshalJSON() ([]byte, error) } type Unmarshaler interface { 
     UnmarshalJSON([]byte) error 
    }
    Copier après la connexion
    Copier après la connexion

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:learnku.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal