Maison > Article > développement back-end > Apprenez à utiliser Json dans Go
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{}
对象,返回[]byte
和error
:
func Marshal(v interface{}) ([]byte, error)
Marshal
函数将会递归遍历整个对象,依次按成员类型对这个对象进行编码,类型转换规则如下:
bool
类型 转换为JSON
的Boolean
整数,浮点数等数值类型 转换为JSON
的Number
string
转换为JSON
的字符串(带””引号)
struct
转换为JSON
的Object
,再根据各个成员的类型递归打包
数组或切片 转换为JSON
的Array
[]byte
会先进行base64
编码然后转换为JSON
字符串
map
转换为JSON
的Object
,key
必须是string
interface{}
按照内部的实际类型进行转换
nil
转为JSON
的null
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
Object
的key
打包成JSON
;Unmashal
时,会自动匹配对应的变量名进行赋值,大小写不敏感。
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
类型,使用时需要再手动转换为需要的int
,int64
等类型。第二个是JSON
的object
自动转换为map[string]interface{}
类型,访问时直接用JSON ``Object
的字段名作为key
进行访问。再不知道JSON
数据的格式时,可以使用interface{}
type Marshaler interface { MarshalJSON() ([]byte, error) } type Unmarshaler interface { UnmarshalJSON([]byte) error }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 : 🎜bool
est converti en booléen
de <code>JSON🎜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🎜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
🎜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 }
实现该接口的对象需要将自己的数据打包和解包。如果实现了该接口,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!