Menu
Coddy logo textTech

Puntatori come valori delle mappe

Fa parte della sezione Logica e flusso del percorso GO di Coddy. Lezione 27 di 68.

Anche se memorizzare le struct direttamente nelle mappe è utile, memorizzare puntatori alle struct sblocca una potente possibilità: modificare direttamente i dati della struct originale tramite la mappa. Questo approccio è essenziale quando devi aggiornare i dati dopo averli memorizzati.

Quando memorizzi un puntatore a una struct come valore di una mappa, stai memorizzando l'indirizzo di memoria della struct, non una sua copia. Ecco come dichiarare e usare una mappa di questo tipo:

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},
}

Il vantaggio principale diventa chiaro quando devi modificare i dati. Poiché stai lavorando con puntatori, le modifiche apportate tramite la mappa influiscono sulla struct originale:

// Actualiza el precio del portátil directamente a través del mapa
products["laptop"].Price = 899.99
fmt.Println(products["laptop"].Price) // imprime: 899.99

Questo schema è particolarmente utile nelle applicazioni in cui devi aggiornare frequentemente i dati memorizzati, come nei sistemi di inventario, nei profili utente o in qualsiasi scenario in cui la mappa funge da archivio dati principale e le modifiche devono essere mantenute.

challenge icon

Sfida

Facile

Crea un semplice sistema di gestione dell'inventario che dimostri i vantaggi dell'uso di puntatori a struct come valori di una mappa. Questa sfida mostra come le mappe basate su puntatori consentano di modificare direttamente i dati memorizzati, rendendo il sistema di inventario efficiente e reattivo agli aggiornamenti.

Riceverai tre input:

  • Una stringa che rappresenta il numero di prodotti (ad es., "4")
  • Una stringa contenente i dati dei prodotti nel formato: "name1:price1:quantity1,name2:price2:quantity2,name3:price3:quantity3" (ad es., "laptop:999.99:5,mouse:25.50:20,keyboard:75.00:15,monitor:299.99:8")
  • Una stringa contenente le operazioni di aggiornamento nel formato: "operation1:product1:value1,operation2:product2:value2", dove le operazioni sono "price" oppure "quantity" (ad es., "price:laptop:899.99,quantity:mouse:25,price:keyboard:65.00")

Il tuo compito è:

  1. Definire una struct Product con i seguenti campi:
    • Price (float64) - il prezzo del prodotto
    • Quantity (int) - la quantità del prodotto in magazzino
  2. Creare una mappa in cui le chiavi sono i nomi dei prodotti (stringhe) e i valori sono puntatori a struct Product
  3. Analizzare i dati dei prodotti dal secondo input:
    • Dividere l'input usando le virgole per ottenere le singole voci dei prodotti
    • Per ogni voce, dividerla usando i due punti per separare il nome, il prezzo e la quantità
    • Convertire la stringa del prezzo in un float64 e la stringa della quantità in un intero
    • Creare una struct Product e memorizzarne un puntatore nella mappa
  4. Durante l'analisi, mantenere i nomi dei prodotti in uno slice separato, nell'ordine in cui compaiono nell'input. In Go, l'iterazione su una mappa visita le chiavi in ordine casuale, quindi è lo slice a mantenere ogni elenco nell'ordine dell'input.
  5. Visualizzare l'inventario iniziale con l'intestazione "Initial Inventory:"
  6. Mostrare ogni prodotto nel formato: "[name]: $[price] (Stock: [quantity])"
  7. Analizzare e applicare le operazioni di aggiornamento dal terzo input:
    • Dividere l'input usando le virgole per ottenere le singole operazioni
    • Per ogni operazione, dividerla usando i due punti per ottenere il tipo di operazione, il nome del prodotto e il nuovo valore
    • Aggiornare direttamente il campo appropriato tramite il puntatore nella mappa
    • Stampare ogni aggiornamento nel formato: "Updated [product]: [field] changed to [new_value]"
  8. Visualizzare l'inventario aggiornato con l'intestazione "Updated Inventory:"
  9. Mostrare di nuovo ogni prodotto usando lo stesso formato della visualizzazione iniziale
  10. Calcolare e visualizzare il valore totale dell'inventario: "Total Inventory Value: $[total_value]"

Usa il package strconv per convertire le stringhe di prezzo e quantità nei rispettivi tipi numerici. Quando visualizzi i prezzi, formattali tutti con 2 cifre decimali. Questa sfida dimostra come memorizzare puntatori nelle mappe permetta di modificare direttamente i dati della struct originale, rendendo gli aggiornamenti dell'inventario immediati e persistenti senza dover riassegnare i valori alla mappa.

Provalo tu

package main

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

func main() {
	// Leggi l'input
	var numProductsStr string
	var productDataStr string
	var operationsStr string
	
	fmt.Scanln(&numProductsStr)
	fmt.Scanln(&productDataStr)
	fmt.Scanln(&operationsStr)
	
	// TODO: Definisci qui la struct Product
	
	// TODO: Crea una mappa per memorizzare i puntatori ai prodotti
	
	// TODO: Crea una slice per mantenere l'ordine dei prodotti (per garantire un output coerente)
	
	// TODO: Analizza i dati dei prodotti e popola la mappa
	// Ricorda di:
	// - Suddividere productDataStr in corrispondenza delle virgole per ottenere le singole voci
	// - Per ogni voce, suddividerla in corrispondenza dei due punti per ottenere nome, prezzo e quantità
	// - Convertire le stringhe del prezzo e della quantità nei tipi appropriati
	// - Memorizzare nella mappa un puntatore alla struct Product
	// - Aggiungere il nome del prodotto alla slice dell'ordine
	
	// TODO: Mostra l'inventario iniziale
	// Usa la slice order per scorrere i prodotti in modo coerente
	// Formato: "[name]: $[price] (Stock: [quantity])"
	
	// TODO: Analizza e applica le operazioni di aggiornamento
	// Ricorda di:
	// - Dividi operationsStr in corrispondenza delle virgole per ottenere le singole operazioni
	// - Per ogni operazione, dividi in corrispondenza dei due punti per ottenere tipo, nome e valore
	// - Aggiorna il campo appropriato direttamente tramite il puntatore nella map
	// - Stampa un messaggio di aggiornamento per ogni operazione
	
	// TODO: Mostra l'inventario aggiornato
	// Usa di nuovo la slice order per ottenere un output coerente
	// Calcola il valore totale mentre visualizzi l'inventario
	
	// TODO: Calcola e mostra il valore totale dell'inventario
	// Formato: "Total Inventory Value: $[total_value]"
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Logica e flusso

Esercitati da solo: Compilatore Go online