Em Go, podes iterar sobre um slice com for e um índice, ou podes usar range. O range também te permite iterar sobre um map.
Cada iteração devolve dois valores: o índice/chave e uma cópia do elemento nesse índice/chave.
Muito simples: iterar sobre um slice com um ciclo, pela ordem esperada.
xi := []int{10, 20, 30}
for i, x := range xi {
fmt.Println(i, x)
}
// outputs:
// 0, 10
// 1, 20
// 2, 30
Iterar sobre um map levanta um novo problema. A ordem é agora aleatória.
hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
fmt.Println(k, v)
}
// outputs, for example:
// 99 20
// 999 30
// 9 10
Pode parecer que o resultado acima está incorreto, porque seria de esperar que o primeiro par chave/valor na declaração do map, 9 10, fosse o primeiro a ser impresso e não o último.
No entanto, os maps não têm ordem por natureza: não existe um primeiro nem um último par chave/valor.
Por isso, ao iterar sobre as entradas de um map, a ordem pela qual as entradas são visitadas é aleatória e não segue nenhum padrão específico.
Isto significa que o resultado acima é possível, mas pode ser diferente daquele que obténs se tentares executar isto tu mesmo.
Para saberes mais sobre isto, consulta Especificação da Linguagem Go: cláusula range.
Em Go, uma variável não usada dá erro em tempo de compilação. Por vezes só precisas do valor, como no primeiro exemplo:
xi := []int{10, 20, 30}
for i, x := range xi {
fmt.Println(x)
}
// Go build failed: i declared but not used
Podes substituir o i por _, o que diz ao compilador que não usamos esse valor:
xi := []int{10, 20, 30}
for _, x := range xi {
fmt.Println(x)
}
// outputs:
// 10
// 20
// 30
Se quiseres imprimir apenas o índice, podes substituir o x por _ ou simplesmente omitir a declaração:
xi := []int{10, 20, 30}
// for i, _ := range xi {
for i := range xi {
fmt.Println(i)
}
// outputs:
// 0
// 1
// 2
Uma definição de tipo cria um novo tipo com nome, distinto de qualquer outro tipo, mesmo de um com o mesmo tipo subjacente.
type File []bool
File refere-se aqui a uma única coluna vertical de um tabuleiro de xadrez, normalmente identificada de A a H.
Cada casa desta coluna é representada por um valor Boolean que indica se está ocupada ou não.
Agora que File está definido, podemos usá-lo dentro de outras definições:
type Chessboard map[string]File
board := Chessboard{
"A": File{true, false, true},
"B": File{false, true, false},
}
Chessboard associa identificadores de coluna a valores File.
Cada File é um slice de Boolean que representa as casas de uma coluna do tabuleiro.
Sem estas definições de tipo, board seria um map[string][]bool, o que tornaria mais difícil perceber o que estamos a representar.
Como entusiasta de xadrez, gostarias de escrever a tua própria versão do jogo. Sim, já devem existir muitas implementações de xadrez disponíveis online, mas a tua vai ser única!
Cada casa do tabuleiro de xadrez é identificada por um par letra-número:
A B C D E F G H
8 # _ _ _ # _ _ # 8
7 _ _ _ _ _ _ _ _ 7
6 _ _ _ _ # _ _ # 6
5 _ # _ _ _ _ _ # 5
4 _ _ _ _ _ _ # # 4
3 # _ # _ _ _ _ # 3
2 _ _ _ _ _ _ _ # 2
1 # _ _ _ _ _ _ # 1
A B C D E F G H
Implementa a função CountInFile(board Chessboard, file string) int.
Deve contar o número total de casas ocupadas percorrendo um mapa.
Devolve um número inteiro.
Devolve uma contagem de zero (0) se a coluna indicada não existir no mapa.
CountInFile(board, "A")
// => 3
Implementa a função CountInRank(board Chessboard, rank int) int.
Deve contar o número total de casas ocupadas percorrendo a fileira indicada.
Devolve um número inteiro.
Devolve uma contagem de zero (0) se a fileira indicada não for válida (não estiver entre 1 e 8, inclusive).
CountInRank(board, 2)
// => 1
Implementa a função CountAll(board Chessboard) int.
Deve contar quantas casas existem no tabuleiro de xadrez e devolve um número inteiro.
Como não precisas de verificar o conteúdo das casas, considera usar range omitindo tanto o index como o value.
CountAll(board)
// => 64
Implementa a função CountOccupied(board Chessboard) int.
Deve contar quantas casas estão ocupadas no tabuleiro de xadrez.
Devolve um número inteiro.
CountOccupied(board)
// => 15
Inscreve-te no Exercism para aprenderes e dominares Go com 34 conceitos166 exercícios, e mentoria humana real, tudo grátis.