Maps
são uma estrutura de dados nativa em Go, conveniente e poderosa com o objetivo de associar valores de um tipo (chaves) a (valores) de outro tipo.
Esse artigo foi baseado no documento, gratuito e disponível em Effective Go
Podendo a chave dessa estrutura ser representada por qualquer tipo em que seja possível utilizar o operador de igualdade, por exemplo,
integer
floating
string
interfaces
structs
arrays
Slices
não podem ser utilizados como chaves em maps
porque o operador de igualdade não implementa o seu tipo em particular.
Assim como os slices
, maps guarda referência para uma estrutura de dados subjacente, logo, caso maps
seja passado por uma função e seja modificado, essas mudanças estarão visíveis para quem chamou a função.
Maps
podem ser construídos em uma composição literal, com separação por virgula para os pares de chave e valor, logo, se torna fácil construí-los na inicialização
var timeZone = map[string]int{
"UTC": 0*60*60,
"EST": -5*60*60,
"CST": -6*60*60,
"MST": -7*60*60,
"PST": -8*60*60,
}
Atribuir e buscar valores é praticamente a mesma coisa do que com arrays
e slices
com exceção de que o indíce não precisa ser um inteiro.
offset := timeZone["EST"]
Ao tentar buscar um valor dentro de um map
em que a chave não esteja presente o retorno será um valor "zerado" correspondendo ao tipo em que as entradas foram definidas. Por exemplo, se um mapa contém integers
a busca não existente retornará 0
. Exemplo, defina o map
com um valor true
para atribuir valor ao conjunto, depois teste com um caso de indexação.
attended := map[string]bool{
"Ann": true,
"Joe": true,
...
}
if attended[person] {
fmt.Println(person, "was at the meeting")
}
Algumas vezes você vai precisar diferenciar uma entrada errada de um valor zero. Existe uma entrada para UTC
ou esse zero é porque não está no map
? Para isso você pode definir uma forma com atribuição múltipla.
var seconds int
var ok bool
seconds, ok = timeZone[tz]
, nesse exemplo, se tz
está contido os seconds
serão atribuídos corretamente e o ok
será verdadeiro. Caso contrário, seconds
será zero e o falor será falso, para essa atribuição chamamos de comma ok idiom
. Aqui está a função que coloca os dois juntos em um bom alerta de erro:
func offset(tz string) int {
if seconds, ok := timeZone[tz]; ok {
return seconds
}
log.Println("unknown time zone:", tz)
return 0
}
Para testar a presença no map
sem precisar saber qual valor em questão, você pode simplesmente usar o operador vazio, identificado com _
no lugar de uma variável.
_, present := timeZone[tz]
Para deletar um dado de um map
, utilize a função nativa delete
, os argumentos a se passar são o próprio map
e a key
(ou chave) para ser deletada.
delete(timeZone, "PDT")