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.99Ce 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.
Défi
FacileConstruisez 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 à :
- Définir une struct
Productavec les champs suivants :Price(float64) - le prix du produitQuantity(int) - la quantité en stock du produit
- 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 - 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
Productet en stocker un pointeur dans la map
- 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.
- Afficher l'inventaire initial avec l'en-tête
"Initial Inventory:" - Afficher chaque produit au format :
"[name]: $[price] (Stock: [quantity])" - 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]"
- Afficher l'inventaire mis à jour avec l'en-tête
"Updated Inventory:" - Afficher à nouveau chaque produit au même format que lors de l'affichage initial
- 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]"
}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
1Structures de contrôle avancées
Switch avec `fallthrough`Sortir de boucles imbriquéesContinuer une boucle spécifiqueL'instruction `goto`Récapitulatif - Contrôle de boucle avancé4Projet : Liste de tâches simple
Configuration du projetAjouter une tâche2Structures et Méthodes
Définir des méthodes sur des structuresReceveurs par valeurReceveurs par pointeurChoisir les receveursMéthodes vs FonctionsRécapitulatif - Comportement des structures5Les Maps en profondeur
Maps de StructsPointeurs comme valeurs de MapTester les Maps NilComparer des MapsRécapitulatif - Compteur de fréquence de mots3Interfaces (Les bases)
Qu'est-ce qu'une Interface ?Définir une InterfaceImplémenter une InterfaceUtiliser les types d'InterfaceInterface videAssertions de typeType SwitchRécapitulatif - Formes et comportementsEntraînez-vous par vous-même : Compilateur Go en ligne