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 maps seja útil, armazenar ponteiros para structs desbloqueia uma capacidade poderosa: a habilidade de modificar os dados da struct original diretamente através do map. Esta abordagem é essencial quando você precisa atualizar seus dados após eles terem sido armazenados.

Quando você armazena um ponteiro para uma struct como um valor de mapa, você 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 torna-se 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:

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

Este padrão é particularmente valioso em aplicações onde você precisa atualizar dados armazenados frequentemente, como sistemas de inventário, perfis de usuário ou qualquer cenário onde o mapa serve como seu armazenamento de dados primário e as modificações precisam persistir.

quiz iconTeste seus conhecimentos

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

quiz iconTeste seus conhecimentos

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

quiz iconTeste seus conhecimentos

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

challenge icon

Desafio

Fácil

Construa um sistema simples de gerenciamento de inventário 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 inventário eficiente e responsivo a atualizações.

Você receberá três entradas:

  • Uma string representando o número de produtos (ex: "4")
  • Uma string contendo os dados dos produtos no formato: "name1:price1:quantity1,name2:price2:quantity2,name3:price3:quantity3" (ex: "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" onde as operações são "price" ou "quantity" (ex: "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 em estoque do produto
  2. Criar um mapa onde as chaves são nomes de produtos (strings) e os valores são ponteiros para structs Product
  3. Analisar os dados dos produtos da segunda entrada:
    • Dividir a entrada por vírgulas para obter as entradas individuais de produtos
    • Para cada entrada, dividir por dois-pontos para separar nome, preço e quantidade
    • Converter a string de preço para um float64 e a string de quantidade para um inteiro
    • Criar uma struct Product e armazenar um ponteiro para ela no mapa
  4. Exibir o inventário inicial com o cabeçalho "Initial Inventory:"
  5. Mostrar cada produto no formato: "[name]: $[price] (Stock: [quantity])"
  6. Analisar e aplicar as operações de atualização 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 de operação, o nome do produto e o novo valor
    • Atualizar o campo apropriado diretamente através do ponteiro no mapa
    • Imprimir cada atualização no formato: "Updated [product]: [field] changed to [new_value]"
  7. Exibir o inventário atualizado com o cabeçalho "Updated Inventory:"
  8. Mostrar cada produto novamente no mesmo formato da exibição inicial
  9. Calcular e exibir o valor total do inventário: "Total Inventory Value: $[total_value]"

Use o pacote strconv para converter as strings de preço e quantidade em seus respectivos tipos numéricos. Formate todos os preços com 2 casas decimais ao exibir. Este desafio demonstra como armazenar ponteiros em mapas permite que você modifique os dados originais da struct diretamente, tornando as atualizações do seu inventário imediatas e persistentes sem a necessidade de reatribuir valores ao mapa.

Folha de consulta

Maps podem armazenar ponteiros para structs, permitindo a modificação direta dos dados da struct original através do 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},
}

Ao usar ponteiros como valores de um map, as modificações feitas através do map afetam a struct original:

// Update the laptop's price directly through the map
products["laptop"].Price = 899.99
fmt.Println(products["laptop"].Price) // imprime: 899.99

Este padrão é valioso para aplicações que exigem atualizações frequentes de dados, como sistemas de inventário ou perfis de usuário, onde o map serve como o armazenamento de dados primário.

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: Definir a struct Product aqui
	
	// TODO: Criar um map para armazenar ponteiros de produtos
	
	// TODO: Criar um slice para manter a ordem dos produtos (para garantir uma saída consistente)
	
	// TODO: Analisar os dados dos produtos e preencher o map
	// Lembre-se de:
	// - Dividir productDataStr por vírgulas para obter entradas individuais
	// - Para cada entrada, dividir por dois pontos para obter nome, preço, quantidade
	// - Converter as strings de preço e quantidade para os tipos apropriados
	// - Armazenar o ponteiro para a struct Product no map
	// - Adicionar o nome do produto ao slice de ordem
	
	// TODO: Exibir o inventário inicial
	// 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:
	// - Dividir operationsStr por vírgulas para obter operações individuais
	// - Para cada operação, dividir por dois pontos para obter tipo, nome, valor
	// - Atualizar o campo apropriado diretamente através do ponteiro do map
	// - Imprimir mensagem de atualização para cada operação
	
	// TODO: Exibir o inventário atualizado
	// Novamente, use o slice de ordem para uma saída consistente
	// Calcular o valor total enquanto exibe
	
	// TODO: Calcular e exibir o valor total do inventário
	// Formato: "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