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 Strukturen in Maps nützlich ist, eröffnet das Speichern von Zeigern auf Strukturen eine leistungsstarke Möglichkeit: die Originaldaten der Struktur direkt über die Map zu ändern. Dieser Ansatz ist unverzichtbar, wenn du deine Daten aktualisieren musst, nachdem sie gespeichert wurden.

Wenn du einen Zeiger auf eine Struktur als Kartenwert speicherst, speicherst du die Speicheradresse der Struktur und nicht deren Kopie. So deklarierst du eine solche Karte und arbeitest mit ihr:

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 du die Daten ändern musst. Da du mit Zeigern arbeitest, wirken sich Änderungen über die map auf die ursprüngliche Struktur aus:

// Aktualisiere 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 du gespeicherte Daten häufig aktualisieren musst, beispielsweise in Bestandsverwaltungssystemen, Benutzerprofilen oder jedem Szenario, in dem die Map als dein primärer Datenspeicher dient und Änderungen dauerhaft gespeichert werden müssen.

challenge icon

Aufgabe

Einfach

Erstelle ein einfaches Bestandsverwaltungssystem, das die Leistungsfähigkeit der Verwendung von Zeigern auf Structs als Map-Werte demonstriert. Diese Herausforderung zeigt, wie pointerbasierte Maps die direkte Änderung gespeicherter Daten ermöglichen und dein Bestandssystem dadurch effizient und reaktionsfähig gegenüber Aktualisierungen wird.

Du erhältst drei Eingaben:

  • Eine Zeichenkette, die die Anzahl der Produkte darstellt (z. B. "4")
  • Eine Zeichenkette mit Produktdaten im Format: "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")
  • Eine Zeichenkette mit Aktualisierungsvorgängen im Format: "operation1:product1:value1,operation2:product2:value2", wobei die Vorgänge entweder "price" oder "quantity" sind (z. B. "price:laptop:899.99,quantity:mouse:25,price:keyboard:65.00")

Deine Aufgabe ist:

  1. Definiere ein Product-Struct mit den folgenden Feldern:
    • Price (float64) – der Preis des Produkts
    • Quantity (int) – die Lagermenge des Produkts
  2. Erstelle eine Map, deren Schlüssel Produktnamen (Zeichenketten) und deren Werte Zeiger auf Product-Structs sind
  3. Verarbeite die Produktdaten aus der zweiten Eingabe:
    • Teile die Eingabe anhand von Kommas auf, um einzelne Produkteinträge zu erhalten
    • Teile jeden Eintrag anhand von Doppelpunkten auf, um Name, Preis und Menge zu trennen
    • Wandle die Preiszeichenkette in einen float64 und die Mengenzeichenkette in eine Ganzzahl um
    • Erstelle ein Product-Struct und speichere einen Zeiger darauf in der Map
  4. Speichere die Produktnamen während der Verarbeitung zusätzlich in einem separaten Slice – in der Reihenfolge, in der sie in der Eingabe vorkommen. Das Durchlaufen einer Map in Go besucht die Schlüssel in zufälliger Reihenfolge, daher sorgt das Slice dafür, dass jede Auflistung in der Reihenfolge der Eingabe bleibt.
  5. Gib den anfänglichen Bestand mit dem Header "Initial Inventory:" aus
  6. Zeige jedes Produkt im Format: "[name]: $[price] (Stock: [quantity])"
  7. Verarbeite die Aktualisierungsvorgänge aus der dritten Eingabe und wende sie an:
    • Teile die Eingabe anhand von Kommas auf, um einzelne Vorgänge zu erhalten
    • Teile jeden Vorgang anhand von Doppelpunkten auf, um Vorgangstyp, Produktname und neuen Wert zu erhalten
    • Aktualisiere das entsprechende Feld direkt über den Map-Zeiger
    • Gib jede Aktualisierung im Format aus: "Updated [product]: [field] changed to [new_value]"
  8. Gib den aktualisierten Bestand mit dem Header "Updated Inventory:" aus
  9. Zeige jedes Produkt erneut im selben Format wie bei der anfänglichen Anzeige
  10. Berechne den Gesamtwert des Bestands und gib ihn aus: "Total Inventory Value: $[total_value]"

Verwende das Paket strconv, um Preis- und Mengenzeichenketten in ihre jeweiligen numerischen Typen umzuwandeln. Formatiere bei der Anzeige alle Preise mit 2 Dezimalstellen. Diese Herausforderung zeigt, wie das Speichern von Zeigern in Maps ermöglicht, die Daten des ursprünglichen Structs direkt zu ändern, sodass deine Bestandsaktualisierungen sofort und dauerhaft übernommen werden, ohne Werte der Map erneut zuweisen zu müssen.

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-Struct hier definieren
	
	// TODO: Map erstellen, um Produkt-Zeiger zu speichern
	
	// TODO: Slice erstellen, um die Produktreihenfolge beizubehalten (um konsistente Ausgabe sicherzustellen)
	
	// TODO: Produktdaten parsen und die Map befüllen
	// Denk daran:
	// - productDataStr anhand von Kommas aufteilen, um einzelne Einträge zu erhalten
	// - Für jeden Eintrag anhand von Doppelpunkten aufteilen, um name, price, quantity zu erhalten
	// - price- und quantity-Strings in passende Typen umwandeln
	// - Zeiger auf Product-Struct in der Map speichern
	// - Produktname zum order-Slice hinzufügen
	
	// TODO: Display initial inventory
	// Verwende den order-Slice, um konsistent durch die Produkte zu iterieren
	// Format: "[name]: $[price] (Stock: [quantity])"
	
	// TODO: Aktualisierungsoperationen parsen und anwenden
	// Denk daran:
	// - operationsStr anhand von Kommas aufteilen, um einzelne Operationen zu erhalten
	// - Für jede Operation anhand von Doppelpunkten aufteilen, um type, name, value zu erhalten
	// - Das entsprechende Feld direkt über den Map-Zeiger aktualisieren
	// - Aktualisierungsnachricht für jede Operation ausgeben
	
	// TODO: Display updated inventory
	// Erneut die order-Slice für konsistente Ausgabe verwenden
	// Gesamtwert während der Anzeige berechnen
	
	// TODO: Calculate and display total inventory value
	// 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

Übe selbstständig: Online-Go-Compiler