Menu
Coddy logo textTech

encoding/json con le struct

Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 76 di 107.

Il pacchetto encoding/json ti permette di convertire le struct Go in JSON e viceversa. Questo è essenziale per le API, i file di configurazione e l'archiviazione dei dati. I tag delle struct controllano come i campi vengono associati alle chiavi JSON.

Per convertire una struct in JSON, usa 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}
}

I tag struct come `json:"name"` specificano i nomi delle chiavi JSON. Senza tag, Go usa direttamente il nome del campo. Nell’output JSON sono inclusi solo i campi esportati (con iniziale maiuscola).

Per convertire JSON di nuovo in una struct, usa json.Unmarshal:

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

Le opzioni comuni dei tag includono omitempty per ignorare i valori zero e - per ignorare completamente un campo:

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

Con omitempty, se Price è zero, non comparirà nel JSON. Il campo Internal non viene mai incluso, indipendentemente dal suo valore.

challenge icon

Sfida

Facile

Creiamo un sistema di catalogo cinematografico che converte tra struct Go e JSON! Ti eserciterai a eseguire il marshaling delle struct in JSON e l'unmarshaling del JSON nelle struct, usando i tag delle struct per controllare i nomi dei campi JSON.

Organizzerai il codice in due file:

  • movie.go: Definisci il modello dei dati dei film con i tag JSON appropriati.

    Crea una struct Movie con i seguenti campi e mappature JSON:

    • Title (string) corrisponde a "title"
    • Director (string) corrisponde a "director"
    • Year (int) corrisponde a "year"
    • Rating (float64) corrisponde a "rating" con omitempty, così i film senza valutazione non mostrano il campo della valutazione
    • InternalID (string) deve essere escluso completamente dal JSON usando "-"

    Crea una funzione ToJSON(m Movie) string che converte una Movie in una stringa JSON. Crea anche FromJSON(jsonStr string) Movie, che analizza una stringa JSON e la riconverte in una struct Movie.

  • main.go: Mostra la conversione JSON in entrambe le direzioni.

    Leggi un tipo di operazione (encode o decode).

    Per encode: Leggi i dettagli del film (titolo, regista, anno, valutazione) su righe separate. Crea una Movie con un InternalID pari a "internal-123", convertila in JSON e stampa il risultato.

    Per decode: Leggi una stringa JSON, convertila in una struct Movie e stampa i dettagli del film in questo formato:

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

    Mostra la valutazione con una cifra decimale. Se la valutazione è 0 (non presente nel JSON), stampa invece Rating: N/A.

Verranno forniti i seguenti input:

  • Riga 1: tipo di operazione (encode o decode)
  • Per encode: titolo, regista, anno, valutazione (quattro righe)
  • Per decode: una stringa JSON (una riga)

Ad esempio, dato:

encode
Inception
Christopher Nolan
2010
8.8

L'output dovrebbe essere:

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

Nota che InternalID non compare nell'output a causa del tag "-".

E dato:

encode
The Matrix
Wachowskis
1999
0

L'output dovrebbe essere:

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

Nota che rating viene omesso perché è zero e ha omitempty.

E dato:

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

L'output dovrebbe essere:

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

E dato:

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

L'output dovrebbe essere:

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

Provalo tu

package main

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

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

	// Leggi il tipo di operazione
	operation, _ := reader.ReadString('\n')
	operation = strings.TrimSpace(operation)

	if operation == "encode" {
		// Leggi i dettagli del 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: Crea una struct Movie con i valori letti
		// Imposta InternalID su "internal-123"
		// Converti in JSON usando ToJSON e stampa il risultato

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

		// TODO: Converti JSON in Movie usando FromJSON
		// Stampa i dettagli del film nel formato richiesto
		// Usa fmt.Sprintf("%.1f", rating) per formattare rating
		// Se rating è 0, stampa invece "Rating: N/A"

	}
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Go online