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 
{}
magiconair
la source

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"}
peterSO
la source
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.

Manohar Reddy Poreddy
la source
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.

Maître GoLang
la source
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))
}
Hieu Vo
la source