Conversion de la structure Go en JSON


181

J'essaie de convertir une structure Go en JSON à l'aide du jsonpackage, mais tout ce que j'obtiens est {}. Je suis certain que c'est quelque chose de totalement évident mais je ne le vois pas.

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    name string
}

func main() {
    user := &User{name:"Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Printf("Error: %s", err)
        return;
    }
    fmt.Println(string(b))
}

Ensuite, quand j'essaye de l'exécuter, j'obtiens ceci:

$ 6g test.go && 6l -o test test.6 && ./test 
{}

Réponses:


331

Vous devez exporter le User.namechamp pour que le jsonpackage puisse le voir. Renommez le namechamp en Name.

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    Name string
}

func main() {
    user := &User{Name: "Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(b))
}

Production:

{"Name":"Frank"}

87
Notez que vous pouvez ajouter `json:"name"`à la fin de la définition du champ struct pour conserver le nom de sortie.
Dustin

12
Je vois. J'aime un peu la langue mais je pense que certains éléments syntaxiques vont trop loin. Si le nom d'un membre de structure détermine le comportement, c'est tout simplement faux.
magiconair

1
Eh bien, faire en sorte que le nom détermine le comportement peut être débattu s'il est bon ou mauvais :) mais cela permet de savoir facilement si un champ est exporté ou non sans avoir à vérifier ailleurs.
Olof

6
@magiconair: La capitalisation de la première rune détermine la visibilité , est une idée beaucoup plus raisonnable que "le nom d'un membre de structure détermine le comportement" . Les métadonnées de visibilité doivent être stockées quelque part et ont besoin d'une syntaxe pour les exprimer. Finalement, il a été déterminé que la cooptation de la capitalisation du premier caractère fonctionne mieux avec le moins de compromis. Avant la sortie de Go1, d'autres projets ont été essayés et rejetés.
deft_code

11
J'ai parcouru un long chemin depuis et j'aime beaucoup le langage, y compris l'exportation par capitalisation, maintenant.
magiconair

62

Problème connexe:

J'avais du mal à convertir la structure en JSON, à l'envoyer comme réponse de Golang, puis à capturer plus tard la même chose en JavaScript via Ajax.

J'ai perdu beaucoup de temps, alors postez la solution ici.

En Go:

// web server

type Foo struct {
    Number int    `json:"number"`
    Title  string `json:"title"`
}

foo_marshalled, err := json.Marshal(Foo{Number: 1, Title: "test"})
fmt.Fprint(w, string(foo_marshalled)) // write response to ResponseWriter (w)

En JavaScript:

// web call & receive in "data", thru Ajax/ other

var Foo = JSON.parse(data);
console.log("number: " + Foo.number);
console.log("title: " + Foo.title);

J'espère que cela aide quelqu'un.
Bonne chance.


6

Les valeurs Struct sont encodées en tant qu'objets JSON. Chaque champ struct exporté devient membre de l'objet sauf si:

  • la balise du champ est "-", ou
  • le champ est vide et sa balise spécifie l'option "omitempty".

Les valeurs vides sont false, 0, tout pointeur ou valeur d'interface nul, et tout tableau, tranche, mappe ou chaîne de longueur zéro. La chaîne de clé par défaut de l'objet est le nom du champ struct mais peut être spécifiée dans la valeur de balise du champ struct. La clé "json" dans la valeur de la balise du champ struct est le nom de la clé, suivi d'une virgule facultative et d'options.


2

Vous pouvez définir vos propres méthodes personnalisées MarshalJSON et UnmarshalJSON et contrôler intentionnellement ce qui doit être inclus, par exemple:

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    name string
}

func (u *User) MarshalJSON() ([]byte, error) {
    return json.Marshal(&struct {
        Name     string `json:"name"`
    }{
        Name:     "customized" + u.name,
    })
}

func main() {
    user := &User{name: "Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(b))
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.