Menu
Coddy logo textTech

Ponteiros como Valores de Map

Parte da seção Lógica & Fluxo do Journey de GO da Coddy. Lição 27 de 68.

Embora armazenar structs diretamente em mapas seja útil, armazenar ponteiros para structs desbloqueia uma poderosa capacidade: a possibilidade de modificar diretamente os dados da struct original por meio do mapa. Essa abordagem é essencial quando você precisa atualizar seus dados depois que eles foram armazenados.

Quando você armazena um ponteiro para uma struct como valor de um mapa, está armazenando o endereço de memória da struct, não uma cópia dela. Veja como declarar e trabalhar com esse tipo de mapa:

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

A principal vantagem fica clara quando você precisa modificar os dados. Como você está trabalhando com ponteiros, as alterações feitas por meio do mapa afetam a struct original:

// Atualize o preço do laptop diretamente através do map
products["laptop"].Price = 899.99
fmt.Println(products["laptop"].Price) // imprime: 899.99

Esse padrão é particularmente valioso em aplicações nas quais você precisa atualizar frequentemente os dados armazenados, como sistemas de inventário, perfis de usuário ou qualquer cenário em que o mapa sirva como seu armazenamento de dados principal e as modificações precisem persistir.

challenge icon

Desafio

Fácil

Crie um sistema simples de gerenciamento de estoque que demonstre o poder de usar ponteiros para structs como valores de um mapa. Este desafio mostra como mapas baseados em ponteiros permitem a modificação direta dos dados armazenados, tornando seu sistema de estoque eficiente e responsivo às atualizações.

Você receberá três entradas:

  • Uma string que representa o número de produtos (por exemplo, "4")
  • Uma string contendo os dados dos produtos no formato: "name1:price1:quantity1,name2:price2:quantity2,name3:price3:quantity3" (por exemplo, "laptop:999.99:5,mouse:25.50:20,keyboard:75.00:15,monitor:299.99:8")
  • Uma string contendo operações de atualização no formato: "operation1:product1:value1,operation2:product2:value2", em que as operações são "price" ou "quantity" (por exemplo, "price:laptop:899.99,quantity:mouse:25,price:keyboard:65.00")

Sua tarefa é:

  1. Definir uma struct Product com os seguintes campos:
    • Price (float64) - o preço do produto
    • Quantity (int) - a quantidade do produto em estoque
  2. Criar um mapa em que as chaves sejam os nomes dos produtos (strings) e os valores sejam ponteiros para structs Product
  3. Analisar os dados dos produtos a partir da segunda entrada:
    • Dividir a entrada por vírgulas para obter as entradas individuais dos produtos
    • Para cada entrada, dividir por dois-pontos para separar o nome, o preço e a quantidade
    • Converter a string do preço para um float64 e a string da quantidade para um inteiro
    • Criar uma struct Product e armazenar um ponteiro para ela no mapa
  4. Manter os nomes dos produtos em uma slice separada durante a análise, na ordem em que aparecem na entrada. Percorrer um mapa em Go visita as chaves em uma ordem aleatória, portanto a slice é o que mantém cada listagem na ordem da entrada.
  5. Exibir o estoque inicial com o cabeçalho "Initial Inventory:"
  6. Exibir cada produto no formato: "[name]: $[price] (Stock: [quantity])"
  7. Analisar e aplicar as operações de atualização a partir da terceira entrada:
    • Dividir a entrada por vírgulas para obter as operações individuais
    • Para cada operação, dividir por dois-pontos para obter o tipo da operação, o nome do produto e o novo valor
    • Atualizar o campo apropriado diretamente por meio do ponteiro no mapa
    • Imprimir cada atualização no formato: "Updated [product]: [field] changed to [new_value]"
  8. Exibir o estoque atualizado com o cabeçalho "Updated Inventory:"
  9. Exibir cada produto novamente no mesmo formato da exibição inicial
  10. Calcular e exibir o valor total do estoque: "Total Inventory Value: $[total_value]"

Use o pacote strconv para converter as strings de preço e quantidade para seus respectivos tipos numéricos. Formate todos os preços com 2 casas decimais ao exibi-los. Este desafio demonstra como armazenar ponteiros em mapas permite modificar diretamente os dados da struct original, tornando as atualizações do estoque imediatas e persistentes, sem a necessidade de reatribuir valores ao mapa.

Experimente você mesmo

package main

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

func main() {
	// Ler a entrada
	var numProductsStr string
	var productDataStr string
	var operationsStr string
	
	fmt.Scanln(&numProductsStr)
	fmt.Scanln(&productDataStr)
	fmt.Scanln(&operationsStr)
	
	// TODO: Defina a struct Product aqui
	
	// TODO: Crie um map para armazenar ponteiros de produtos
	
	// TODO: Crie um slice para manter a ordem dos produtos (para garantir saída consistente)
	
	// TODO: Faça o parse dos dados dos produtos e popule o map
	// Lembre-se de:
	// - Divida productDataStr por vírgulas para obter as entradas individuais
	// - Para cada entrada, divida por dois-pontos para obter name, price, quantity
	// - Converta as strings de price e quantity para os tipos apropriados
	// - Armazene o ponteiro para a struct Product no map
	// - Adicione o name do produto ao slice de ordem
	
	// TODO: Display initial inventory
	// Use o slice de ordem para iterar pelos produtos de forma consistente
	// Formato: "[name]: $[price] (Stock: [quantity])"
	
	// TODO: Analisar e aplicar as operações de atualização
	// Lembre-se de:
	// - Divida operationsStr por vírgulas para obter as operações individuais
	// - Para cada operação, divida por dois-pontos para obter type, name, value
	// - Atualize o campo apropriado diretamente através do ponteiro do map
	// - Imprima a mensagem de atualização para cada operação
	
	// TODO: Display updated inventory
	// Novamente, use o slice order para uma saída consistente
	// Calcule o valor total enquanto exibe
	
	// TODO: Calculate and display total inventory value
	// Format: "Total Inventory Value: $[total_value]"
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Lógica & Fluxo

Pratique por conta própria: Compilador de Go online