Menu
Coddy logo textTech

encoding/json ze strukturami

Część sekcji Programowanie obiektowe ścieżki GO w Coddy. Lekcja 76 z 107.

Pakiet encoding/json pozwala konwertować struktury Go na JSON i z powrotem. Jest to niezbędne w przypadku interfejsów API, plików konfiguracyjnych i przechowywania danych. Tagi struktur kontrolują sposób mapowania pól na klucze JSON.

Aby przekonwertować strukturę na JSON, użyj 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}
}

Tagi struktury, takie jak `json:"name"`, określają nazwy kluczy JSON. Bez tagów Go używa bezpośrednio nazwy pola. W wyniku JSON uwzględniane są tylko eksportowane pola (zaczynające się wielką literą).

Aby przekonwertować JSON z powrotem na strukturę, użyj json.Unmarshal:

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

Typowe opcje tagów obejmują omitempty, aby pomijać wartości zerowe, oraz -, aby całkowicie ignorować pole:

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

Dzięki omitempty, jeśli Price ma wartość zero, nie pojawi się w JSON. Pole Internal nigdy nie jest uwzględniane, niezależnie od swojej wartości.

challenge icon

Wyzwanie

Łatwy

Stwórzmy system katalogu filmów, który konwertuje między strukturami Go a JSON! Poćwiczysz serializowanie struktur do JSON i deserializowanie JSON z powrotem do struktur, używając tagów struktur do kontrolowania nazw pól JSON.

Rozmieścisz swój kod w dwóch plikach:

  • movie.go: Zdefiniuj model danych filmu z odpowiednimi tagami JSON.

    Utwórz strukturę Movie z następującymi polami i mapowaniami JSON:

    • Title (string) mapuje na "title"
    • Director (string) mapuje na "director"
    • Year (int) mapuje na "year"
    • Rating (float64) mapuje na "rating" z omitempty, aby filmy bez oceny nie wyświetlały pola oceny
    • InternalID (string) powinno być całkowicie wykluczone z JSON przy użyciu "-"

    Utwórz funkcję ToJSON(m Movie) string, która konwertuje Movie na ciąg JSON. Utwórz też FromJSON(jsonStr string) Movie, która analizuje ciąg JSON i konwertuje go z powrotem na strukturę Movie.

  • main.go: Zademonstruj konwersję JSON w obu kierunkach.

    Odczytaj typ operacji (encode lub decode).

    Dla encode: Odczytaj szczegóły filmu (tytuł, reżyser, rok, ocena) w osobnych wierszach. Utwórz Movie z InternalID o wartości "internal-123", przekonwertuj go na JSON i wyświetl wynik.

    Dla decode: Odczytaj ciąg JSON, przekonwertuj go na strukturę Movie i wyświetl szczegóły filmu w następującym formacie:

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

    Wyświetl ocenę z jednym miejscem po przecinku. Jeśli ocena wynosi 0 (nie występuje w JSON), wyświetl Rating: N/A.

Dane wejściowe będą następujące:

  • Wiersz 1: Typ operacji (encode lub decode)
  • Dla encode: tytuł, reżyser, rok, ocena (cztery wiersze)
  • Dla decode: ciąg JSON (jeden wiersz)

Na przykład, dla danych:

encode
Inception
Christopher Nolan
2010
8.8

Wynik powinien być następujący:

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

Zauważ, że InternalID nie pojawia się w wyniku ze względu na tag "-".

A dla danych:

encode
The Matrix
Wachowskis
1999
0

Wynik powinien być następujący:

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

Zauważ, że rating jest pomijane, ponieważ jego wartość wynosi zero i ma tag omitempty.

A dla danych:

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

Wynik powinien być następujący:

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

A dla danych:

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

Wynik powinien być następujący:

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

Spróbuj swoich sił

package main

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

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

	// Odczytaj typ operacji
	operation, _ := reader.ReadString('\n')
	operation = strings.TrimSpace(operation)

	if operation == "encode" {
		// Odczytaj dane filmu
		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: Utwórz strukturę Movie z odczytanymi wartościami
		// Ustaw InternalID na "internal-123"
		// Przekonwertuj na JSON za pomocą ToJSON i wypisz wynik

	} else if operation == "decode" {
		// Odczytaj ciąg znaków JSON
		jsonStr, _ := reader.ReadString('\n')
		jsonStr = strings.TrimSpace(jsonStr)

		// TODO: Przekonwertuj JSON na Movie za pomocą FromJSON
		// Wypisz dane filmu w wymaganym formacie
		// Użyj fmt.Sprintf("%.1f", rating) do sformatowania rating
		// Jeśli rating wynosi 0, wypisz zamiast tego "Rating: N/A"

	}
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Go online