Pour générer le JSON Représentation d'une valeur Go, le package encoding/json
vérifie si la valeur implémente les interfaces json.Marshaler
ou encoding.TextMarshaler
, et si c'est le cas, elles sont utilisées/appelées (dans cet ordre). Ceci est documenté à json.Marshal()
:
Marshal traverse la valeur v de manière récursive. Si une valeur rencontrée implémente l'interface Marshaler et n'est pas un pointeur nul, Marshal appelle sa méthode MarshalJSON pour produire JSON. Si aucune méthode MarshalJSON n'est présente mais que la valeur implémente encoding.TextMarshaler à la place, Marshal appelle sa méthode MarshalText et code le résultat en tant que chaîne JSON.
Le package json/encoding
ne se soucie pas de la méthode String()
. Donc, si vous voulez contrôler la représentation JSON/sortie de votre valeur (la struct Ticket
), mettre en œuvre json.Marshaler
sur elle (dans lequel vous pouvez appeler String()
à votre goût):
func (t Ticket) MarshalJSON() ([]byte, error) {
return []byte(`"` + t.String() + `"`), nil
}
Ensuite, la sortie sera comme vous désir:
{"Name":"John","Ticket":"New York - Washington"}
Essayez-le sur le Go Playground.
Une chose à regarder dehors pour: si le string
produit par Ticket.String()
contiendrait un guillemet "
, la sortie deviendrait invalide JSON, ou plus probablement json.Marshal()
retournerait une erreur.
Pour prendre soin de ces Escaping, le meilleur/plus simple est d'utiliser lui-même le paquet json
: dire à JSON-encode le résultat string
de Ticket.String()
:
func (t Ticket) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
Maintenant, si nous testons comme ça :
p.Name = "John"
p.Tkt.From = "New\" York" // CONTAINS QUOTE
p.Tkt.To = "Washington"
buf, err := json.Marshal(p)
fmt.Println(string(buf), err)
la sortie sera toujours un JSON valide (essayer sur le Go Playground):
{"Name":"John","Ticket":"New\" York - Washington"} <nil>
Solution merveilleuse. Je vous remercie. –
Incidemment, vous pouvez simplement utiliser '% q' au lieu de'% s' et il vous indiquera la chaîne. https://play.golang.org/p/RYhaMM5kpd – Kaedys
@Kaedys Vous m'avez fait réaliser que j'avais oublié les citations potentielles dans l'entrée. J'ai mis à jour la question pour suggérer l'utilisation du paquet 'json' pour prendre soin de ceux-ci. – icza