Sobes.tech
Middle

Por que não se pode pegar a referência ao valor armazenado por chave no mapa?

sobes.tech IA

Resposta da IA

No Golang, um mapa (map) representa uma tabela de dispersão. Adicionar ou remover elementos pode levar a alterações na estrutura interna do mapa, incluindo a redistribuição de memória e o movimento de elementos. Se pegar um ponteiro para o valor armazenado por chave e depois modificar o mapa (por exemplo, adicionando ou removendo outro elemento), esse ponteiro pode tornar-se inválido, apontando para uma região de memória incorreta ou para outro valor. Golang impede isso na fase de compilação, proibindo de tirar o endereço de um elemento do mapa.

Além disso, em Golang, um mapa não é seguro para uso concorrente (thread-safe). Modificar diretamente um valor através de um ponteiro poderia causar condições de corrida se múltiplas goroutines acessarem em paralelo, dificultando a sincronização. A proibição de tirar um ponteiro de um valor no mapa simplifica o modelo de acesso concorrente e torna explícita a necessidade de usar mecanismos de sincronização (por exemplo, sync.RWMutex) ao trabalhar com mapas em ambientes multithread.

Para modificar um valor por chave, deve-se obter o valor, modificá-lo e depois guardar o valor modificado de volta no mapa:

package main

import "fmt"

func main() {
	m := map[string]int{"a": 1}

	// Não é possível tirar um ponteiro do valor no mapa
	// ptr := &m["a"] // Erro de compilação

	// A forma correta de modificar o valor:
	value := m["a"] // Obter o valor
	value++         // Modificar o valor
	m["a"] = value  // Guardar o valor modificado

	fmt.Println(m["a"]) // Vai imprimir 2
}