Menu
Coddy logo textTech

encoding/json mit Structs

Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy. Lektion 76 von 107.

Das Paket encoding/json ermöglicht es dir, Go-Strukturen in JSON umzuwandeln und zurück. Das ist für APIs, Konfigurationsdateien und die Datenspeicherung unerlässlich. Struktur-Tags steuern, wie Felder JSON-Schlüsseln zugeordnet werden.

Um eine Struktur in JSON zu konvertieren, verwende 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}
}

Struct-Tags wie `json:"name"` geben die JSON-Schlüsselnamen an. Ohne Tags verwendet Go direkt den Feldnamen. Nur exportierte Felder (mit Großbuchstaben) werden in die JSON-Ausgabe aufgenommen.

Um JSON wieder in eine Struktur umzuwandeln, verwende json.Unmarshal:

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

Zu den gängigen Tag-Optionen gehören omitempty, um Nullwerte zu überspringen, und -, um ein Feld vollständig zu ignorieren:

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

Mit omitempty wird Price, wenn es null ist, nicht im JSON erscheinen. Das Feld Internal wird unabhängig von seinem Wert niemals einbezogen.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Filmkatalogsystem, das zwischen Go-Strukturen und JSON konvertiert! Du übst, Strukturen in JSON zu marshallen und JSON zurück in Strukturen zu unmarshallen, wobei du Struct-Tags verwendest, um die JSON-Feldnamen zu steuern.

Du organisierst deinen Code auf zwei Dateien verteilt:

  • movie.go: Definiere dein Filmdatenmodell mit den passenden JSON-Tags.

    Erstelle eine Movie-Struktur mit den folgenden Feldern und JSON-Zuordnungen:

    • Title (string) wird "title" zugeordnet
    • Director (string) wird "director" zugeordnet
    • Year (int) wird "year" zugeordnet
    • Rating (float64) wird "rating" mit omitempty zugeordnet, damit Filme ohne Bewertung kein Bewertungsfeld anzeigen
    • InternalID (string) soll mithilfe von "-" vollständig aus JSON ausgeschlossen werden

    Erstelle eine Funktion ToJSON(m Movie) string, die ein Movie in einen JSON-String konvertiert. Erstelle außerdem FromJSON(jsonStr string) Movie, die einen JSON-String zurück in eine Movie-Struktur parst.

  • main.go: Demonstriere die JSON-Konvertierung in beide Richtungen.

    Lies einen Operationstyp (encode oder decode) ein.

    Bei encode: Lies die Filmdetails (Titel, Regisseur, Jahr, Bewertung) in separaten Zeilen ein. Erstelle ein Movie mit einer InternalID von "internal-123", konvertiere es in JSON und gib das Ergebnis aus.

    Bei decode: Lies einen JSON-String ein, konvertiere ihn in eine Movie-Struktur und gib die Filmdetails in diesem Format aus:

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

    Gib die Bewertung mit einer Nachkommastelle aus. Wenn die Bewertung 0 ist (nicht in JSON vorhanden), gib stattdessen Rating: N/A aus.

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Operationstyp (encode oder decode)
  • Für encode: Titel, Regisseur, Jahr, Bewertung (vier Zeilen)
  • Für decode: ein JSON-String (eine Zeile)

Beispiel bei folgender Eingabe:

encode
Inception
Christopher Nolan
2010
8.8

Deine Ausgabe sollte sein:

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

Beachte, dass InternalID aufgrund des "-"-Tags nicht in der Ausgabe erscheint.

Und bei folgender Eingabe:

encode
The Matrix
Wachowskis
1999
0

Deine Ausgabe sollte sein:

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

Beachte, dass rating ausgelassen wird, weil es null ist und omitempty verwendet.

Und bei folgender Eingabe:

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

Deine Ausgabe sollte sein:

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

Und bei folgender Eingabe:

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

Deine Ausgabe sollte sein:

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

Probier es selbst

package main

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

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

	// Operationstyp lesen
	operation, _ := reader.ReadString('\n')
	operation = strings.TrimSpace(operation)

	if operation == "encode" {
		// Filmdetails lesen
		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: Erstelle eine Movie-Struktur mit den gelesenen Werten
		// Setze InternalID auf "internal-123"
		// Konvertiere mit ToJSON zu JSON und gib das Ergebnis aus

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

		// TODO: Konvertiere JSON mit FromJSON zu Movie
		// Gib die Filmdetails im erforderlichen Format aus
		// Verwende fmt.Sprintf("%.1f", rating) für die Formatierung der Bewertung
		// Wenn rating 0 ist, gib stattdessen "Rating: N/A" aus

	}
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Go-Compiler