Menu
Coddy logo textTech

Pointer als Map-Werte

Teil des Abschnitts Logik & Ablauf der GO-Journey von Coddy — Lektion 27 von 68.

Während das direkte Speichern von Structs in Maps nützlich ist, schaltet das Speichern von Pointern auf Structs eine leistungsstarke Funktion frei: die Fähigkeit, die ursprünglichen Struct-Daten direkt über die Map zu ändern. Dieser Ansatz ist unerlässlich, wenn Sie Ihre Daten aktualisieren müssen, nachdem sie gespeichert wurden.

Wenn Sie einen Zeiger auf ein Struct als Map-Wert speichern, speichern Sie die Speicheradresse des Structs, nicht eine Kopie davon. So deklarieren und arbeiten Sie mit einer solchen Map:

type Product struct {
    Price    float64
    Quantity int
}

products := map[string]*Product{
    "laptop": &Product{Price: 999.99, Quantity: 5},
    "mouse":  &Product{Price: 25.50, Quantity: 20},
}

Der entscheidende Vorteil wird deutlich, wenn Sie die Daten ändern müssen. Da Sie mit Pointern arbeiten, wirken sich Änderungen, die über die Map vorgenommen werden, auf das ursprüngliche Struct aus:

// Aktualisieren Sie den Preis des Laptops direkt über die Map
products["laptop"].Price = 899.99
fmt.Println(products["laptop"].Price) // gibt aus: 899.99

Dieses Muster ist besonders wertvoll in Anwendungen, in denen Sie gespeicherte Daten häufig aktualisieren müssen, wie z. B. Inventarsysteme, Benutzerprofile oder jedes Szenario, in dem die Map als Ihr primärer Datenspeicher dient und Änderungen dauerhaft gespeichert werden müssen.

quiz iconTeste dich selbst

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

quiz iconTeste dich selbst

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

quiz iconTeste dich selbst

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

challenge icon

Aufgabe

Einfach

Erstellen Sie ein einfaches Bestandsverwaltungssystem, das die Vorteile der Verwendung von Pointern auf Structs als Map-Werte demonstriert. Diese Herausforderung zeigt, wie Pointer-basierte Maps die direkte Änderung gespeicherter Daten ermöglichen, wodurch Ihr Inventarsystem effizient wird und schnell auf Aktualisierungen reagiert.

Sie erhalten drei Eingaben:

  • Einen String, der die Anzahl der Produkte darstellt (z. B. "4")
  • Einen String, der Produktdaten im Format enthält: "name1:price1:quantity1,name2:price2:quantity2,name3:price3:quantity3" (z. B. "laptop:999.99:5,mouse:25.50:20,keyboard:75.00:15,monitor:299.99:8")
  • Einen String, der Aktualisierungsoperationen im Format enthält: "operation1:product1:value1,operation2:product2:value2" wobei Operationen entweder "price" oder "quantity" sind (z. B. "price:laptop:899.99,quantity:mouse:25,price:keyboard:65.00")

Ihre Aufgabe ist es:

  1. Definieren Sie ein Product Struct mit den folgenden Feldern:
    • Price (float64) - der Preis des Produkts
    • Quantity (int) - die Lagerbestandsmenge des Produkts
  2. Erstellen Sie eine Map, in der die Schlüssel Produktnamen (Strings) und die Werte Pointer auf Product Structs sind
  3. Verarbeiten Sie die Produktdaten aus der zweiten Eingabe:
    • Teilen Sie die Eingabe durch Kommas auf, um einzelne Produkteinträge zu erhalten
    • Teilen Sie jeden Eintrag durch Doppelpunkte auf, um Name, Preis und Menge zu trennen
    • Konvertieren Sie den Preis-String in einen float64 und den Mengen-String in einen Integer
    • Erstellen Sie ein Product Struct und speichern Sie einen Pointer darauf in der Map
  4. Zeigen Sie das ursprüngliche Inventar mit der Kopfzeile "Initial Inventory:" an
  5. Geben Sie jedes Produkt im Format: "[name]: $[price] (Stock: [quantity])" aus
  6. Verarbeiten und wenden Sie die Aktualisierungsoperationen aus der dritten Eingabe an:
    • Teilen Sie die Eingabe durch Kommas auf, um einzelne Operationen zu erhalten
    • Teilen Sie jede Operation durch Doppelpunkte auf, um Operationstyp, Produktname und neuen Wert zu erhalten
    • Aktualisieren Sie das entsprechende Feld direkt über den Map-Pointer
    • Geben Sie jede Aktualisierung im Format: "Updated [product]: [field] changed to [new_value]" aus
  7. Zeigen Sie das aktualisierte Inventar mit der Kopfzeile "Updated Inventory:" an
  8. Geben Sie jedes Produkt erneut im gleichen Format wie bei der ursprünglichen Anzeige aus
  9. Berechnen und zeigen Sie den Gesamtwert des Inventars an: "Total Inventory Value: $[total_value]"

Verwenden Sie das strconv Paket, um Preis- und Mengen-Strings in ihre jeweiligen numerischen Typen zu konvertieren. Formatieren Sie alle Preise bei der Anzeige auf 2 Dezimalstellen. Diese Herausforderung zeigt, wie das Speichern von Pointern in Maps es Ihnen ermöglicht, die ursprünglichen Struct-Daten direkt zu ändern, wodurch Ihre Inventaraktualisierungen sofort und dauerhaft erfolgen, ohne dass Werte der Map neu zugewiesen werden müssen.

Spickzettel

Maps können Pointer auf Structs speichern, was die direkte Änderung der ursprünglichen Struct-Daten über die Map ermöglicht:

type Product struct {
    Price    float64
    Quantity int
}

products := map[string]*Product{
    "laptop": &Product{Price: 999.99, Quantity: 5},
    "mouse":  &Product{Price: 25.50, Quantity: 20},
}

Wenn Pointer als Map-Werte verwendet werden, wirken sich Änderungen über die Map auf das ursprüngliche Struct aus:

// Den Preis des Laptops direkt über die Map aktualisieren
products["laptop"].Price = 899.99
fmt.Println(products["laptop"].Price) // gibt aus: 899.99

Dieses Muster ist wertvoll für Anwendungen, die häufige Datenaktualisierungen erfordern, wie z. B. Inventarsysteme oder Benutzerprofile, bei denen die Map als primärer Datenspeicher dient.

Probier es selbst

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {
	// Eingabe lesen
	var numProductsStr string
	var productDataStr string
	var operationsStr string
	
	fmt.Scanln(&numProductsStr)
	fmt.Scanln(&productDataStr)
	fmt.Scanln(&operationsStr)
	
	// TODO: Product-Struktur hier definieren
	
	// TODO: Map erstellen, um Produkt-Pointer zu speichern
	
	// TODO: Slice erstellen, um die Produktreihenfolge beizubehalten (für konsistente Ausgabe)
	
	// TODO: Produktdaten parsen und die Map befüllen
	// Nicht vergessen:
	// - productDataStr nach Kommas trennen, um einzelne Einträge zu erhalten
	// - Jeden Eintrag nach Doppelpunkten trennen, um Name, Preis und Menge zu erhalten
	// - Preis- und Mengen-Strings in entsprechende Typen umwandeln
	// - Pointer zur Product-Struktur in der Map speichern
	// - Produktnamen zum Order-Slice hinzufügen
	
	// TODO: Anfangsbestand anzeigen
	// Den Order-Slice verwenden, um Produkte konsistent zu durchlaufen
	// Format: "[name]: $[price] (Stock: [quantity])"
	
	// TODO: Aktualisierungsoperationen parsen und anwenden
	// Nicht vergessen:
	// - operationsStr nach Kommas trennen, um einzelne Operationen zu erhalten
	// - Jede Operation nach Doppelpunkten trennen, um Typ, Name und Wert zu erhalten
	// - Das entsprechende Feld direkt über den Map-Pointer aktualisieren
	// - Aktualisierungsnachricht für jede Operation ausgeben
	
	// TODO: Aktualisierten Bestand anzeigen
	// Wieder den Order-Slice für eine konsistente Ausgabe verwenden
	// Gesamtwert während der Anzeige berechnen
	
	// TODO: Gesamtwert des Bestands berechnen und anzeigen
	// Format: "Total Inventory Value: $[total_value]"
}
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 Logik & Ablauf