Menu
Coddy logo textTech

Pointeurs comme valeurs de Map

Fait partie de la section Logique & Flux du Journey GO de Coddy. Leçon 27 sur 68.

Bien que le stockage direct de structures dans des maps soit utile, le stockage de pointeurs vers des structures permet une fonctionnalité puissante : la possibilité de modifier directement les données de la structure d’origine via la map. Cette approche est essentielle lorsque vous devez mettre à jour vos données après leur stockage.

Lorsque tu stockes un pointeur vers une structure comme valeur d’une map, tu stockes l’adresse mémoire de la structure, et non une copie de celle-ci. Voici comment déclarer et utiliser une telle 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},
}

L’avantage principal devient évident lorsque vous devez modifier les données. Comme vous travaillez avec des pointeurs, les modifications effectuées via la map affectent la structure d’origine :

// Mettre à jour le prix du laptop directement via la map
products["laptop"].Price = 899.99
fmt.Println(products["laptop"].Price) // affiche : 899.99

Ce modèle est particulièrement utile dans les applications où vous devez mettre fréquemment à jour les données stockées, comme les systèmes d’inventaire, les profils utilisateur ou tout scénario dans lequel la map sert de magasin de données principal et où les modifications doivent être conservées.

challenge icon

Défi

Facile

Construisez un système simple de gestion d'inventaire qui démontre la puissance de l'utilisation de pointeurs vers des structs comme valeurs d'une map. Ce défi montre comment les maps basées sur des pointeurs permettent de modifier directement les données stockées, rendant votre système d'inventaire efficace et réactif aux mises à jour.

Vous recevrez trois entrées :

  • Une chaîne représentant le nombre de produits (par exemple, "4")
  • Une chaîne contenant les données des produits au format : "name1:price1:quantity1,name2:price2:quantity2,name3:price3:quantity3" (par exemple, "laptop:999.99:5,mouse:25.50:20,keyboard:75.00:15,monitor:299.99:8")
  • Une chaîne contenant les opérations de mise à jour au format : "operation1:product1:value1,operation2:product2:value2", où les opérations sont soit "price", soit "quantity" (par exemple, "price:laptop:899.99,quantity:mouse:25,price:keyboard:65.00")

Votre tâche consiste à :

  1. Définir une struct Product avec les champs suivants :
    • Price (float64) - le prix du produit
    • Quantity (int) - la quantité en stock du produit
  2. Créer une map où les clés sont les noms des produits (chaînes) et les valeurs sont des pointeurs vers des structs Product
  3. Analyser les données des produits de la deuxième entrée :
    • Diviser l'entrée par des virgules pour obtenir les différentes entrées de produits
    • Pour chaque entrée, la diviser par des deux-points afin de séparer le nom, le prix et la quantité
    • Convertir la chaîne du prix en float64 et la chaîne de la quantité en entier
    • Créer une struct Product et en stocker un pointeur dans la map
  4. Conserver les noms des produits dans une slice séparée lors de l'analyse, dans l'ordre où ils apparaissent dans l'entrée. Parcourir une map avec une boucle en Go visite les clés dans un ordre aléatoire ; la slice permet donc de conserver chaque produit dans l'ordre de l'entrée.
  5. Afficher l'inventaire initial avec l'en-tête "Initial Inventory:"
  6. Afficher chaque produit au format : "[name]: $[price] (Stock: [quantity])"
  7. Analyser et appliquer les opérations de mise à jour de la troisième entrée :
    • Diviser l'entrée par des virgules pour obtenir les différentes opérations
    • Pour chaque opération, la diviser par des deux-points afin d'obtenir le type d'opération, le nom du produit et la nouvelle valeur
    • Mettre à jour directement le champ approprié via le pointeur de la map
    • Afficher chaque mise à jour au format : "Updated [product]: [field] changed to [new_value]"
  8. Afficher l'inventaire mis à jour avec l'en-tête "Updated Inventory:"
  9. Afficher à nouveau chaque produit au même format que lors de l'affichage initial
  10. Calculer et afficher la valeur totale de l'inventaire : "Total Inventory Value: $[total_value]"

Utilisez le package strconv pour convertir les chaînes de prix et de quantité en leurs types numériques respectifs. Formatez tous les prix avec 2 décimales lors de l'affichage. Ce défi démontre que le stockage de pointeurs dans des maps permet de modifier directement les données de la struct d'origine, rendant les mises à jour de votre inventaire immédiates et persistantes, sans avoir besoin de réaffecter les valeurs dans la map.

Essayez vous-même

package main

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

func main() {
	// Lire l'entrée
	var numProductsStr string
	var productDataStr string
	var operationsStr string
	
	fmt.Scanln(&numProductsStr)
	fmt.Scanln(&productDataStr)
	fmt.Scanln(&operationsStr)
	
	// TODO: Définir la structure Product ici
	
	// TODO: Créer une map pour stocker les pointeurs de produits
	
	// TODO: Créer une slice pour maintenir l'ordre des produits (pour assurer une sortie cohérente)
	
	// TODO: Analyser les données des produits et peupler la map
	// N'oubliez pas de :
	// - Diviser productDataStr par des virgules pour obtenir les entrées individuelles
	// - Pour chaque entrée, diviser par des deux-points pour obtenir name, price, quantity
	// - Convertir les chaînes price et quantity en types appropriés
	// - Stocker le pointeur vers la structure Product dans la map
	// - Ajouter le nom du produit à la slice order
	
	// TODO: Display initial inventory
	// Utiliser la slice order pour parcourir les produits de manière cohérente
	// Format : "[name]: $[price] (Stock: [quantity])"
	
	// TODO: Analyser et appliquer les opérations de mise à jour
	// N'oubliez pas de :
	// - Diviser operationsStr par des virgules pour obtenir les opérations individuelles
	// - Pour chaque opération, diviser par des deux-points pour obtenir type, name, value
	// - Mettre à jour le champ approprié directement via le pointeur de la map
	// - Afficher le message de mise à jour pour chaque opération
	
	// TODO: Display updated inventory
	// À nouveau, utiliser le slice order pour une sortie cohérente
	// Calculer la valeur totale pendant l'affichage
	
	// TODO: Calculate and display total inventory value
	// Format: "Total Inventory Value: $[total_value]"
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Logique & Flux

Entraînez-vous par vous-même : Compilateur Go en ligne