Linive
Posted on May 24, 2020
Hoje vamos falar um pouco mais sobre loops.
Vocês já ouviram valar sobre o for range
?
Calma que não é esse tipo de ranger...
Ele é outra versão do loop for, muito utilizado com slices, arrays, maps e strings. O que esses tipos têm em comum? São compostos por um grupo de outros elementos.
Ainda não vimos slices, arrays e maps, apenas sabemos que são tipos compostos, ou seja, formado por tipos primitivos. Mas já conhecemos bem o tipo string.
Sabemos que a string é uma cadeia de caracteres, ou runes, e que uma rune é do tipo int32
, podendo ter até 4 bytes. Já aprendemos a transformar caracteres em slice of bytes, sabemos que existe a tabela ASCII, o UTF-8 e o unicode, entre outras coisas. Por isso vamos aprender o for range
com strings.
Esse é o for range
:
serie := "modern family"
for indice, valor := range serie {
fmt.Printf("índice: %v - valor: %v\n", indice, valor)
}
/*
resultado:
índice: 0 - valor: 109
índice: 1 - valor: 111
índice: 2 - valor: 100
índice: 3 - valor: 101
índice: 4 - valor: 114
índice: 5 - valor: 110
índice: 6 - valor: 32
índice: 7 - valor: 102
índice: 8 - valor: 97
índice: 9 - valor: 109
índice: 10 - valor: 105
índice: 11 - valor: 108
índice: 12 - valor: 121
*/
O resultado foi numérico, se você leu o post de conversão 👇🏽:
Já deve saber exatamente o que aconteceu, o tipo deixou de ser string e passou a ser int32, que é o tipo de um caractere. Esses números que saíram no resultado podem ser encontrados na tabela ASCII, o número 32, por exemplo, é referente ao espaço que existe na string.
Vamos conhecer parte por parte do for range
.
serie := "modern family"
for indice, valor := range serie {...}
O range
vai percorrer toda a extensão da string, ele vai pulando de letra em letra a cada volta do loop. Toda vez que ele mudar de letra irá retornar dois valores, o índice e o valor daquele caractere.
O indice
indicará a localização do caractere na string. Começando do zero até finalizar toda a extensão da variável. O espaço está na localização 6, lembrando que começamos a contar sempre do zero.
Muitas pessoas chamam o índice de i
.
Já o valor, value, irá receber a informação do valor daquele caractere.
Podemos chama-lo apenas de v
.
Juntando as duas informações i
e v
, conseguimos indicar a localização e o valor das letras: fmt.Printf("indice: %v, valor: %v", i, v)
.
Se não precisarmos de um desses valores, podemos apenas ignora-lo utilizando o underline _
.
serie := "modern family"
for _, valor := range serie {...}
//Estou ignorando o índice
Para exibir as letras como caracteres, podemos converter novamente para strings.
serie := "modern family"
for i, v := range serie {
fmt.Printf("índice: %v - valor: %v - letra: %s\n", i, v, string(v))
}
/*
resultado:
índice: 0 - valor: 109 - letra: m
índice: 1 - valor: 111 - letra: o
índice: 2 - valor: 100 - letra: d
índice: 3 - valor: 101 - letra: e
índice: 4 - valor: 114 - letra: r
índice: 5 - valor: 110 - letra: n
índice: 6 - valor: 32 - letra:
índice: 7 - valor: 102 - letra: f
índice: 8 - valor: 97 - letra: a
índice: 9 - valor: 109 - letra: m
índice: 10 - valor: 105 - letra: i
índice: 11 - valor: 108 - letra: l
índice: 12 - valor: 121 - letra: y
*/
Muitas das coisas que fazemos com o for range também podem ser feitas com o for normal, esse exemplo é uma delas.
Apenas precisamos conhecer a funcionalidade do len
. Length que dizer comprimento, extensão. Ele pegará o comprimento da minha string e assim poderemos fazer o for normal de acordo com a extensão, assim como o for range.
serie := "modern family"
for i := 0; i < len(serie); i++ {//enquanto i for menor que a extensão da string
fmt.Printf("índice: %v - valor: %v - letra: %s\n", i, serie[i], string(serie[i]))
}
Outra diferença é esse tal de serie[i]
. O for normal não irá pular de letra em letra automaticamente igual ao range. Então temos que indicar de alguma forma que a cada loop iremos mudar de letra. Por isso utilizamos o serie[i]
.
Essa estrutura é muito utilizada em arrays e slices. Colocamos o nome da variável e o índice que queremos fica dentro dos colchetes. Como o i
começa do zero e será incrementado a cada volta do loop, ele será nosso índice.
O resultado dos dois for
será exatamente o mesmo, mas nem sempre será assim. Vamos ver o que acontece se um caractere ocupar mais de um byte.
sdds := "São João"
for i, v := range sdds{
fmt.Printf("índice: %v - valor: %v - letra: %s\n", i, v, string(v))
}
/*
resultado:
índice: 0 - valor: 83 - letra: S
índice: 1* - valor: 227 - letra: ã
índice: 3* - valor: 111 - letra: o
índice: 4 - valor: 32 - letra:
índice: 5 - valor: 74 - letra: J
índice: 6 - valor: 111 - letra: o
índice: 7* - valor: 227 - letra: ã
índice: 9* - valor: 111 - letra: o
*/
No for range
não aconteceu nenhuma mudança. Mas percebam que os índices estão pulando alguns números, ele foi de 1 para 3 e de 7 para 9.
Vamos ver no for
:
sdds:= "São João"
for i := 0; i < len(sdds); i++ {
fmt.Printf("índice: %v - valor: %v - letra: %s\n", i, sdds[i], string(sdds[i]))
}
/*
Resultado:
índice: 0 - valor: 83 - letra: S
índice: 1 - valor: 195 - letra: Ã*
índice: 2 - valor: 163 - letra: £*
índice: 3 - valor: 111 - letra: o
índice: 4 - valor: 32 - letra:
índice: 5 - valor: 74 - letra: J
índice: 6 - valor: 111 - letra: o
índice: 7 - valor: 195 - letra: Ã*
índice: 8 - valor: 163 - letra: £*
índice: 9 - valor: 111 - letra: o
*/
Os índices não pularam nenhum número, mas em compensação alguns caracteres estranhos apareceram.
Isso aconteceu pois existem letras acentuadas, elas ocupam 2 bytes, diferente das outras. O for range
percorrer caractere por caractere (int32
), não importando quantos bytes eles ocupam. Já o for
irá de byte por byte (uint8
), então se uma letra ocupar mais de um byte, o for irá mostrar.
Essa é uma diferença sutil, mas as vezes o resultado não sai como o esperado e não sabemos o motivo.
Hoje conhecemos o for range
e trabalhamos um pouco mais com o for
, espero que tenham entendido e procurem exercitar e experimentar mais os dois.
Se quiserem me acompanhar nos estudos: É só clicar aqui e ser feliz.
A missão de hoje foi realizada com sucesso, até amanhã.
Posted on May 24, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.