Menu
Coddy logo textTech

encoding/json avec des structs

Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy. Leçon 76 sur 107.

Le package encoding/json vous permet de convertir des structs Go en JSON et inversement. C’est essentiel pour les API, les fichiers de configuration et le stockage des données. Les balises de struct contrôlent la manière dont les champs correspondent aux clés JSON.

Pour convertir une struct en JSON, utilisez json.Marshal :

type User struct {
    Name  string `json:"name"`
    Email string `json:"email"`
    Age   int    `json:"age"`
}

func main() {
    user := User{Name: "Alice", Email: "alice@example.com", Age: 30}
    data, _ := json.Marshal(user)
    fmt.Println(string(data))
    // {"name":"Alice","email":"alice@example.com","age":30}
}

Les balises de structure comme `json:"name"` spécifient les noms des clés JSON. Sans balises, Go utilise directement le nom du champ. Seuls les champs exportés (commençant par une majuscule) sont inclus dans la sortie JSON.

Pour reconvertir du JSON en une structure, utilisez json.Unmarshal :

jsonStr := `{"name":"Bob","email":"bob@example.com","age":25}`
var user User
json.Unmarshal([]byte(jsonStr), &user)
fmt.Println(user.Name)  // Bob

Les options de balises courantes incluent omitempty pour ignorer les valeurs par défaut et - pour ignorer complètement un champ :

type Product struct {
    ID       int    `json:"id"`
    Name     string `json:"name"`
    Price    float64 `json:"price,omitempty"`
    Internal string `json:"-"`
}

Avec omitempty, si Price vaut zéro, il n'apparaîtra pas dans le JSON. Le champ Internal n'est jamais inclus, quelle que soit sa valeur.

challenge icon

Défi

Facile

Construisons un système de catalogue de films qui convertit des structures Go en JSON et inversement ! Tu vas t’entraîner à sérialiser des structures en JSON et à désérialiser du JSON en structures, en utilisant des balises de structure pour contrôler les noms des champs JSON.

Tu vas organiser ton code dans deux fichiers :

  • movie.go : définis ton modèle de données de film avec les balises JSON appropriées.

    Crée une structure Movie avec les champs et les correspondances JSON suivants :

    • Title (string) correspond à "title"
    • Director (string) correspond à "director"
    • Year (int) correspond à "year"
    • Rating (float64) correspond à "rating" avec omitempty, afin que les films sans note n’affichent pas de champ de note
    • InternalID (string) doit être complètement exclu du JSON à l’aide de "-"

    Crée une fonction ToJSON(m Movie) string qui convertit un Movie en chaîne JSON. Crée également FromJSON(jsonStr string) Movie qui analyse une chaîne JSON pour la reconvertir en structure Movie.

  • main.go : montre la conversion JSON dans les deux sens.

    Lis un type d’opération (encode ou decode).

    Pour encode : lis les détails du film (titre, réalisateur, année, note) sur des lignes séparées. Crée un Movie avec un InternalID égal à "internal-123", convertis-le en JSON et affiche le résultat.

    Pour decode : lis une chaîne JSON, convertis-la en structure Movie et affiche les détails du film dans ce format :

    Title: [title]
    Director: [director]
    Year: [year]
    Rating: [rating]

    Affiche la note avec une décimale. Si la note est égale à 0 (absente du JSON), affiche Rating: N/A à la place.

Les entrées suivantes seront fournies :

  • Ligne 1 : type d’opération (encode ou decode)
  • Pour encode : titre, réalisateur, année, note (quatre lignes)
  • Pour decode : une chaîne JSON (une ligne)

Par exemple, avec :

encode
Inception
Christopher Nolan
2010
8.8

Ta sortie doit être :

{"title":"Inception","director":"Christopher Nolan","year":2010,"rating":8.8}

Remarque que InternalID n’apparaît pas dans la sortie à cause de la balise "-".

Et avec :

encode
The Matrix
Wachowskis
1999
0

Ta sortie doit être :

{"title":"The Matrix","director":"Wachowskis","year":1999}

Remarque que rating est omis, car sa valeur est zéro et qu’il possède omitempty.

Et avec :

decode
{"title":"Interstellar","director":"Christopher Nolan","year":2014,"rating":8.6}

Ta sortie doit être :

Title: Interstellar
Director: Christopher Nolan
Year: 2014
Rating: 8.6

Et avec :

decode
{"title":"Tenet","director":"Christopher Nolan","year":2020}

Ta sortie doit être :

Title: Tenet
Director: Christopher Nolan
Year: 2020
Rating: N/A

Essayez vous-même

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Lire le type d'opération
	operation, _ := reader.ReadString('\n')
	operation = strings.TrimSpace(operation)

	if operation == "encode" {
		// Lire les détails du film
		title, _ := reader.ReadString('\n')
		title = strings.TrimSpace(title)

		director, _ := reader.ReadString('\n')
		director = strings.TrimSpace(director)

		yearStr, _ := reader.ReadString('\n')
		yearStr = strings.TrimSpace(yearStr)
		year, _ := strconv.Atoi(yearStr)

		ratingStr, _ := reader.ReadString('\n')
		ratingStr = strings.TrimSpace(ratingStr)
		rating, _ := strconv.ParseFloat(ratingStr, 64)

		// TODO: Créer une struct Movie avec les valeurs lues
		// Définir InternalID à "internal-123"
		// Convertir en JSON en utilisant ToJSON et afficher le résultat

	} else if operation == "decode" {
		// Lire la chaîne JSON
		jsonStr, _ := reader.ReadString('\n')
		jsonStr = strings.TrimSpace(jsonStr)

		// TODO: Convertir le JSON en Movie en utilisant FromJSON
		// Afficher les détails du film au format requis
		// Utiliser fmt.Sprintf("%.1f", rating) pour le formatage de rating
		// Si rating est 0, afficher "Rating: N/A" à la place

	}
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur Go en ligne