Exercício - Use mapas
Um mapa em Go é uma tabela hash, que é uma coleção de pares de chaves e valores. Todas as chaves em um mapa devem ser do mesmo tipo, assim como os valores. Mas, você pode usar diferentes tipos para chaves e valores. Por exemplo, as chaves podem ser números e os valores podem ser cadeias de caracteres. Para acessar um item específico em um mapa, você faz referência à sua chave.
Declarar e inicializar um mapa
Para declarar um mapa, você precisa usar a map
palavra-chave. Em seguida, você define a chave e o tipo de valor, assim: map[T]T
. Por exemplo, se você quiser criar um mapa que contenha a idade dos alunos, você pode usar o seguinte código:
package main
import "fmt"
func main() {
studentsAge := map[string]int{
"john": 32,
"bob": 31,
}
fmt.Println(studentsAge)
}
Quando você executa o código anterior, você vê a seguinte saída:
map[bob:31 john:32]
Se não quiser inicializar um mapa com itens, você pode usar a função interna make()
para criar o mapa na seção anterior. Você pode usar o seguinte código para criar um mapa vazio:
studentsAge := make(map[string]int)
Os mapas são dinâmicos. Você pode adicionar, acessar ou remover itens depois de criá-los. Vamos explorar essas ações.
Adicionar itens
Para adicionar itens, você não precisa usar uma função interna como faz com fatias. Os mapas são mais simples. Você só precisa definir uma chave e um valor. Se o par não existir, o item é adicionado ao mapa.
Vamos reescrever o código que usamos anteriormente para criar um mapa usando a make
função. Em seguida, adicionaremos itens ao mapa. Você pode usar o seguinte código:
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println(studentsAge)
}
Quando você executa o código, você obtém a mesma saída que antes:
map[bob:31 john:32]
Observe que adicionamos itens a um mapa que foi inicializado. Mas se você tentar fazer o mesmo com um nil
mapa, você receberá um erro. Por exemplo, o seguinte código não funcionará:
package main
import "fmt"
func main() {
var studentsAge map[string]int
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println(studentsAge)
}
Quando você executa o código anterior, você obtém o seguinte erro:
panic: assignment to entry in nil map
goroutine 1 [running]:
main.main()
/Users/johndoe/go/src/helloworld/main.go:7 +0x4f
exit status 2
Para evitar problemas ao adicionar itens a um mapa, certifique-se de criar um mapa vazio (não um nil
mapa) usando a make
função como mostramos no trecho de código anterior. Esta regra só se aplica quando adiciona itens. Se você executar pesquisas, exclusões ou operações de loop em um nil
mapa, o Go não entrará em pânico. Confirmaremos esse comportamento daqui a pouco.
Itens de acesso
Para acessar itens em um mapa, use a notação m[key]
subscrita usual, como faz com matrizes ou fatias. Aqui está um exemplo simples de como acessar um item:
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println("Bob's age is", studentsAge["bob"])
}
Quando você usa a notação subscrita em um mapa, sempre recebe uma resposta de volta, mesmo que a chave não esteja presente em um mapa. Go não entra em pânico quando você acessa um item que não existe. Em vez disso, você recebe o valor padrão de volta. Você pode confirmar esse comportamento usando o seguinte código:
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println("Christy's age is", studentsAge["christy"])
}
Quando você executa o código anterior, você vê a seguinte saída:
Christy's age is 0
Em muitos casos, é justo que o Go não retorne um erro quando você acessa um item que não existe em um mapa. Mas há momentos em que você precisa saber se um item existe ou não. Em Go, a notação subscrita para um mapa pode produzir dois valores. O primeiro é o valor de um item. O segundo é um sinalizador booleano que indica se a chave existe ou não.
Para corrigir o problema com o último trecho de código, você pode usar o seguinte código:
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
age, exist := studentsAge["christy"]
if exist {
fmt.Println("Christy's age is", age)
} else {
fmt.Println("Christy's age couldn't be found")
}
}
Quando você executa o código anterior, você vê a seguinte saída:
Christy's age couldn't be found
Use o segundo trecho de código para verificar se existe uma chave em um mapa antes de acessá-lo.
Remover itens
Para remover um item de um mapa, use a função interna delete()
. Eis um exemplo de como remover itens de um mapa:
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
delete(studentsAge, "john")
fmt.Println(studentsAge)
}
Quando você executa o código, você obtém a seguinte saída:
map[bob:31]
Como dissemos anteriormente, se você tentar excluir um item que não existe, o Go não entrará em pânico. Aqui está um exemplo desse comportamento:
package main
import "fmt"
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
delete(studentsAge, "christy")
fmt.Println(studentsAge)
}
Quando você executa o código, você não recebe um erro e você vê a seguinte saída:
map[bob:31 john:32]
Loop em um mapa
Por fim, vamos ver como você pode fazer um loop em um mapa para acessar todos os seus itens programaticamente. Para fazer isso, você pode usar o loop baseado em intervalo, como este exemplo:
package main
import (
"fmt"
)
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
for name, age := range studentsAge {
fmt.Printf("%s\t%d\n", name, age)
}
}
Quando você executa o código anterior, você vê a seguinte saída:
john 32
bob 31
Observe como você pode armazenar as informações de chave e valor em diferentes variáveis. Neste caso, estamos segurando a chave na name
variável e o valor na age
variável. Assim, range
produz primeiro a chave de um item e, em segundo lugar, o valor desse item. Você pode ignorar qualquer um deles usando a _
variável, como este exemplo:
package main
import (
"fmt"
)
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
for _, age := range studentsAge {
fmt.Printf("Ages %d\n", age)
}
}
Mesmo que, neste caso, não faça sentido imprimir as idades dessa forma, haverá casos em que você não precisa saber a chave de um item. Como alternativa, você pode usar apenas a chave do item, como este exemplo:
package main
import (
"fmt"
)
func main() {
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
for name := range studentsAge {
fmt.Printf("Names %s\n", name)
}
}