Menu
Coddy logo textTech

Podstawy osadzania struktur

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

Osadzanie struktur to mechanizm języka Go umożliwiający umieszczenie jednego typu struktury wewnątrz innej. Zamiast używać nazwy pola, po prostu podajesz typ, a Go udostępnia pola osadzonej struktury w strukturze zewnętrznej.

Oto podstawowa składnia:

type Address struct {
    City    string
    Country string
}

type Person struct {
    Name string
    Address  // osadzone - bez nazwy pola
}

Gdy osadzisz Address w Person, możesz uzyskać bezpośredni dostęp do osadzonych pól w zewnętrznej strukturze:

func main() {
    p := Person{
        Name: "Alice",
        Address: Address{
            City:    "London",
            Country: "UK",
        },
    }
    
    fmt.Println(p.City)     // London - dostęp bezpośredni
    fmt.Println(p.Country)  // UK - dostęp bezpośredni
    fmt.Println(p.Address.City)  // również działa
}

Zwróć uwagę, że p.City działa bez konieczności jawnego zapisywania p.Address.City. Go automatycznie udostępnia pola osadzonej struktury tak, jakby należały do zewnętrznej struktury. W razie potrzeby nadal możesz uzyskać do nich dostęp za pomocą nazwy osadzonego typu.

To różni się od zwykłych zagnieżdżonych struktur, w których zawsze musisz używać nazwy pola, aby uzyskać dostęp do pól wewnętrznych. Osadzanie tworzy bardziej płaskie i wygodniejsze API, jednocześnie zachowując logiczne grupowanie powiązanych danych.

challenge icon

Wyzwanie

Łatwy

Stwórzmy system rejestracji pojazdów, który wykorzystuje osadzanie struktur, aby utworzyć przejrzysty i uporządkowany model danych. Oddzielisz informacje kontaktowe od danych pojazdu, zachowując jednocześnie bezpośredni dostęp do wszystkich pól dzięki osadzaniu.

Rozmieścisz kod w dwóch plikach:

  • vehicle.go: Utwórz dwie struktury, które współpracują dzięki osadzaniu:
    • Strukturę ContactInfo z polami OwnerName i Phone (oba typu string)
    • Strukturę Vehicle, która osadza ContactInfo (bez nazwy pola) i dodaje własne pola Make, Model i Year
    Utwórz również metodę o nazwie Summary dla Vehicle, która zwraca sformatowany ciąg zawierający wszystkie informacje o pojeździe i dane kontaktowe.
  • main.go: Odczytaj z wejścia dane pojazdu i właściciela, utwórz instancję Vehicle z osadzonym ContactInfo i pokaż, jak uzyskać dostęp do osadzonych pól zarówno bezpośrednio, jak i przez nazwę osadzonego typu. Na końcu wypisz podsumowanie pojazdu.

Podane zostaną następujące dane wejściowe:

  • Wiersz 1: Imię i nazwisko właściciela
  • Wiersz 2: Numer telefonu
  • Wiersz 3: Marka pojazdu
  • Wiersz 4: Model pojazdu
  • Wiersz 5: Rok (liczba całkowita)

Metoda Summary powinna zwracać ciąg w następującym formacie:

[Year] [Make] [Model] - Owner: [OwnerName], Phone: [Phone]

W pliku głównym pokaż promocję pól, wypisując:

  1. Imię i nazwisko właściciela uzyskane bezpośrednio z Vehicle (np. v.OwnerName)
  2. Numer telefonu uzyskany przez osadzony typ (np. v.ContactInfo.Phone)
  3. Pełne podsumowanie z metody Summary

Na przykład dla danych Alice Smith, 555-1234, Toyota, Camry i 2023 wynik powinien wyglądać następująco:

Alice Smith
555-1234
2023 Toyota Camry - Owner: Alice Smith, Phone: 555-1234

Zwróć uwagę, że oba sposoby dostępu działają: bezpośredni dostęp dzięki promocji pól oraz jawny dostęp przez nazwę osadzonego typu. Daje ci to elastyczność w pracy z osadzonymi danymi.

Spróbuj swoich sił

package main

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

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

	// Odczytaj imię i nazwisko właściciela
	ownerName, _ := reader.ReadString('\n')
	ownerName = strings.TrimSpace(ownerName)

	// Odczytaj numer telefonu
	phone, _ := reader.ReadString('\n')
	phone = strings.TrimSpace(phone)

	// Odczytaj markę pojazdu
	make, _ := reader.ReadString('\n')
	make = strings.TrimSpace(make)

	// Odczytaj model pojazdu
	model, _ := reader.ReadString('\n')
	model = strings.TrimSpace(model)

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

	// TODO: Utwórz instancję Vehicle z osadzonym ContactInfo
	// Użyj wartości odczytanych powyżej z wejścia

	// TODO: Wypisz imię i nazwisko właściciela, uzyskując do nich dostęp bezpośrednio przez Vehicle (promowanie pól)
	// Przykład: fmt.Println(v.OwnerName)

	// TODO: Wypisz numer telefonu, uzyskując do niego dostęp przez nazwę osadzonego typu
	// Przykład: fmt.Println(v.ContactInfo.Phone)

	// TODO: Wypisz pełne podsumowanie za pomocą metody Summary
	// Przykład: fmt.Println(v.Summary())

	// Usuń te linie po zaimplementowaniu rozwiązania
	_ = ownerName
	_ = phone
	_ = make
	_ = model
	_ = year
}
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