DEV Community

Linive
Linive

Posted on

Loop for range em go

Hoje vamos falar um pouco mais sobre loops.

Vocês já ouviram valar sobre o for range?

Alt Text

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ã.

Alt Text

Top comments (0)