Résumé du comportement de conversion de go json

J'ai essayé divers comportements json de go, je vais donc les résumer.

Comment convertir en json

Tout d'abord, comment convertir en json. Le moyen le plus simple de procéder est de faire quelque chose comme ceci:

import "encoding/json"
//...
jsonout, err := json.Marshal(Objet cible)

Cette méthode est facile à comprendre, mais en réalité, elle est souvent convertie sous la forme suivante.

encoder := json.NewEncoder(io où json est écrit.Writer)
err := encoder.Encode(Objet cible)

Avec la méthode ci-dessus, n'importe quelle interface de io.Writer peut être utilisée, vous pouvez donc écrire dans un fichier (os.File), écrire dans une réponse http (http.ResponseWriter) ou dans un tampon (bufio.Writer). Il a un haut degré de liberté, comme l'écriture.

Sortie de base

Ensuite, regardons la sortie de la structure de base. La sortie de json pour une structure normale comme celle ci-dessous est la suivante.

func main() {
  type Sample struct {
    IDString string
  }
  st := Sample{IDString: "xxfff"}
  out, _ := json.Marshal(st)
  fmt.Println(string(out)) // []Puisqu'il s'agit d'un type d'octet, il est converti en chaîne
  // Output:
  // {"IDString":"xxfff"}
}

Il s'agit d'une image dans laquelle la structure est directement convertie en json. C'est intuitif. Cependant, compte tenu de la convention de nommage de json, il est subtil de savoir si cela est pratique. Beaucoup de gens pensent que le nom clé de json est un chameau inférieur et est souvent un cas de serpent. Pour ce faire, vous devez changer le nom de la clé. Pour modifier le nom de la clé, utilisez le caractère de balise. Le cas où le nom de la clé est modifié est le suivant.

func main() {
  type Sample struct {
    IDString string `json:"id_string"`
  }

  st := Sample{IDString: "xxfff"}
  out, _ := json.Marshal(st)
  fmt.Println(string(out)) // []Puisqu'il s'agit d'un type d'octet, il est converti en chaîne
  // Output:
  // {"id_string":"xxfff"}
}

Beaucoup de gens trouvent difficile d'insérer les caractères de balise un par un. Cependant, il n'y a pas d'options intéressantes dans la bibliothèque officielle json, donc tout le monde fait de son mieux en utilisant Tools.

À propos de la balise JSON

Le format de la balise json est le suivant.

`(...) json:"[<key>][,<flag1>[,<flag2>]]" (...)`

Comme mentionné ci-dessus, il existe des balises json qui peuvent être spécifiées autrement que par la modification du nom de la clé. Les éléments qui peuvent être spécifiés sont les suivants.

--Nom de clé

Nom de la clé

Comme son nom l'indique, cet élément est un champ de nom de clé json. Comme cela sera décrit plus loin, il s'agit de la priorité la plus élevée parmi les spécifications de nom de clé. Si vous spécifiez -, ce champ sera ignoré. Si rien n'est écrit et que «,» est écrit, le nom du champ de la structure est utilisé comme d'habitude.

omitempty

Si cet élément est spécifié, la valeur sera ignorée lorsque la valeur est zéro. Dans le cas du langage go, la valeur initiale est traitée comme une valeur nulle, je pense donc que cet élément ne doit pas être utilisé pour des types autres que le type pointeur. L'image est la suivante.

func main() {
  type Sample struct {
    ID      string  `json:",omitempty"`
    Pointer *string `json:",omitempty"`
  }
  s := Sample{ID: "", Pointer: nil}
  out, _ := json.Marshal(s)
  fmt.Println(string(out)) // []Puisqu'il s'agit d'un type d'octet, il est converti en chaîne
  // Output:
  // {}
}

string

Cet élément est assez spécial personnellement et change la valeur en type de chaîne. Les types intégrés suivants sont pris en charge.

De plus, comme le type de chaîne est également converti en type de chaîne, " est échappé et sorti.

func main() {
  type Sample struct {
    ID string `json:",string"`
  }
  s := Sample{ID: "xxffid"}
  out, _ := json.Marshal(s)
  fmt.Println(string(out)) // []Puisqu'il s'agit d'un type d'octet, il est converti en chaîne
  // Output:
  // {"ID":"\"xxffid\""}
}

Ordre de sortie

L'ordre de sortie est similaire à l'ordre des champs dans la structure. Cependant, les éléments comme la carte qui ne sont pas dans un ordre fixe sont triés par ordre alphabétique par nom de clé. Je me suis demandé pourquoi c'était l'ordre, mais vu la facilité des tests, je me sens comme ça.

func main() {
	s := map[string]string{
		"cup":    "one",
		"apple":  "two",
		"banana": "three",
	}
	out, _ := json.Marshal(s)
	fmt.Println(string(out)) // []Puisqu'il s'agit d'un type d'octet, il est converti en chaîne
	// Output:
	// {"apple":"two","banana":"three","cup":"one"}
}

Type intégré

La structure du langage go peut être intégrée. Étant donné que ce type ne spécifie pas de nom de champ, il n'y a pas de nom de clé. Par conséquent, fondamentalement, les champs de la structure intégrée sont développés et sortis.

func main() {
  type Emb struct {
    Content string
  }
  type Sample struct {
    Emb
  }
  s := Sample{Emb: Emb{Content: "string"}}
  out, _ := json.Marshal(s)
  fmt.Println(string(out)) // []Puisqu'il s'agit d'un type d'octet, il est converti en chaîne
  // Output: {"Content":"string"}
}

Bien sûr, il y a des exceptions, comme je l'ai dit de base. Le langage go autorise les déclarations de type pour les tableaux. Dans ce cas, le nom de la clé est inconnu car l'extension entraînera l'extension de la baie. Par conséquent, le nom du type est le nom de la clé, à l'exception du type incorporé du tableau.

func main() {
  type Emb []string
  type Sample struct {
    Emb
  }
  s := Sample{Emb: Emb{"content1", "content2"}}
  out, _ := json.Marshal(s)
  fmt.Println(string(out)) // []Puisqu'il s'agit d'un type d'octet, il est converti en chaîne
  // Output:
  // {"Emb":["content1","content2"]}
}

Priorité du nom de clé

D'après l'explication jusqu'à présent, vous pouvez voir que le nom de la clé est déterminé par divers facteurs. Cependant, cela entraînerait un conflit clé. Par conséquent, la conversion json de go est prioritaire. Les priorités sont indiquées ci-dessous.

  1. Nom de clé spécifié par balise
  2. Nom de champ normal
  3. Intégré (la même priorité s'applique aux champs intégrés)

S'il y a plusieurs éléments avec la même priorité, aucune valeur de clé ne sera sortie et aucune erreur ne sera sortie. C'est un comportement qui semble convenir si vous ne faites pas attention lors du déploiement du type intégré.

Publicité

Il existe différents comportements, mais je pense que beaucoup de gens trouvent gênant de se souvenir de chacun d'eux et d'y penser un par un. J'ai donc créé un outil pour savoir ce que json produit la structure. https://github.com/komem3/stout

Pour l'utiliser, spécifiez simplement le chemin du fichier et le nom de la structure comme indiqué ci-dessous.

stout -path ./define.go SimpleStruct

Je l'ai écrit pour cette promotion.

Références

Recommended Posts

Résumé du comportement de conversion de go json
Résumé de l'extrait de code lors du développement avec Go
Comportement de multiprocessing.pool.Pool.map
Classe pour convertir JSON
Conversion par lots de fichiers Excel en JSON [Python]
Résumé de Tensorflow / Keras
Résumé de l'utilisation de pyenv
Caractéristiques du langage Go
Résumé des arguments Python
Résumé de la méthode d'essai
résumé lié à l'opération de fichier python
Résumé des opérations de liste Python3
2017.3.6 ~ 3.12 Résumé de ce que nous avons fait
comportement de matplotlib: histgramme normé
Résumé d'utilisation pratique de Flask
Résumé des types de distribution Linux
Résumé de l'utilisation de base de Pandas
Comportement de la méthode pandas rolling ()
Un bref résumé de Linux
Résumé des paramètres de connexion proxy