Aprendendo Go: Maps

Daniel SuhettDaniel Suhett
3 min read

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")
1
Subscribe to my newsletter

Read articles from Daniel Suhett directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Daniel Suhett
Daniel Suhett

"Enquanto viver, continue aprendendo a viver." Seneca