Arrays em Rust
Um array é uma lista de valores de tamanho fixo, todos do mesmo tipo. “Tamanho fixo” é a parte importante: depois que você cria um array, ele não cresce nem diminui. Se você precisa de algo que muda de tamanho, é para isso que existe o vetor.
Criando um array
Seção intitulada “Criando um array”fn main() { let numbers: [i32; 5] = [1, 2, 3, 4, 5]; println!("{:?}", numbers);}O tipo [i32; 5] se lê como “um array de 5 valores i32”. Esse tamanho faz parte do tipo: [i32; 5] e [i32; 3] são considerados tipos diferentes.
Você também pode deixar o Rust deduzir o tipo e escrever só os valores:
let numbers = [1, 2, 3, 4, 5];O mesmo valor repetido
Seção intitulada “O mesmo valor repetido”Para preencher um array com o mesmo valor N vezes, use este atalho:
fn main() { let zeros = [0; 5]; // [0, 0, 0, 0, 0] println!("{:?}", zeros);}Acessando os elementos
Seção intitulada “Acessando os elementos”Os índices de um array começam em 0, e você usa colchetes para acessar cada posição:
fn main() { let fruits = ["maçã", "banana", "cereja"];
println!("{}", fruits[0]); // maçã println!("{}", fruits[2]); // cereja println!("Tamanho: {}", fruits.len());}O acesso fora dos limites é detectado
Seção intitulada “O acesso fora dos limites é detectado”Se você tentar acessar um índice que não existe, o Rust interrompe o programa em vez de ler lixo da memória sem avisar:
fn get_fruit(fruits: [&str; 3], index: usize) -> &str { fruits[index]}
fn main() { let fruits = ["maçã", "banana", "cereja"]; println!("{}", get_fruit(fruits, 10)); // dá panic em tempo de execução}thread 'main' (12345) panicked at src/main.rs:2:5:index out of bounds: the len is 3 but the index is 10A mensagem está em inglês porque é o que o Rust imprime: ela diz que o índice está fora dos limites, já que o tamanho é 3 e o índice pedido é 10.
Percorrendo um array
Seção intitulada “Percorrendo um array”fn main() { let numbers = [10, 20, 30];
for n in numbers { println!("{n}"); }}Arrays de arrays (arrays 2D)
Seção intitulada “Arrays de arrays (arrays 2D)”Um array pode guardar outros arrays. Isso dá uma grade com linhas e colunas, como um tabuleiro de jogo ou uma planilha pequena. O tipo de grid abaixo é [[i32; 3]; 2], que se lê como “2 linhas, cada uma um array de 3 valores i32”.
fn main() { // 2 linhas, 3 colunas let grid = [ [1, 2, 3], [4, 5, 6], ];
println!("Linha 1, coluna 2: {}", grid[1][2]);
let mut total = 0; for row in grid { println!("{:?}", row); for value in row { total += value; } } println!("Total: {total}");}Saída:
Linha 1, coluna 2: 6[1, 2, 3][4, 5, 6]Total: 21grid[1][2] quer dizer “linha 1 e, dentro dessa linha, coluna 2”. As duas contagens começam em 0, então essa é a segunda linha, terceiro valor. Para passar por todos os valores, use um laço para as linhas e um segundo laço dentro dele para os valores de cada linha.
Todas as linhas precisam ter o mesmo tamanho, porque o tamanho da linha faz parte do tipo. Se você também precisar da posição durante o laço, .iter().enumerate() entrega o índice e o valor juntos. Isso aparece na página do laço for.
Arrays ou vetores?
Seção intitulada “Arrays ou vetores?”Use um array quando o tamanho é fixo e conhecido de antemão (como os sete dias da semana). Use um Vec quando você precisa adicionar ou remover itens, o que, na prática, acontece na maioria das vezes. No código Rust do dia a dia, arrays aparecem bem menos do que vetores.
Prática
Seção intitulada “Prática”1. Soma e média
Seção intitulada “1. Soma e média”Crie o array [4, 8, 15, 16, 23, 42]. Some todos os valores e imprima a soma e a média com duas casas decimais. Dica: percorra com for, mantenha um total acumulado e converta os dois números para f64 com as antes de dividir.
Ver solução
fn main() { let numbers = [4, 8, 15, 16, 23, 42];
let mut total = 0; for n in numbers { total += n; }
let average = total as f64 / numbers.len() as f64; println!("Soma: {total}"); println!("Média: {average:.2}");}Saída:
Soma: 108Média: 18.00Sem o as f64, total / numbers.len() seria uma divisão inteira, e o Rust ainda reclamaria que total (um i32) e len() (um usize) são de tipos diferentes.
2. O dia mais quente
Seção intitulada “2. O dia mais quente”Você tem as temperaturas de uma semana: [18, 25, 12, 31, 22, 27, 19]. Encontre e imprima a maior. Dica: comece com let mut hottest = temps[0]; e depois percorra o array, trocando o valor sempre que encontrar um maior.
Ver solução
fn main() { let temps = [18, 25, 12, 31, 22, 27, 19];
let mut hottest = temps[0]; for t in temps { if t > hottest { hottest = t; } }
println!("Dia mais quente: {hottest}");}Saída:
Dia mais quente: 31Começar com temps[0] em vez de 0 faz diferença: se todas as temperaturas fossem abaixo de zero, começar com 0 daria uma resposta errada.
- Arrays têm um tamanho fixo, que faz parte do tipo:
[i32; 5]. - Acesse os elementos com
array[index], começando em 0. - Um acesso fora dos limites causa panic em tempo de execução, em vez de comportamento indefinido.
- Arrays podem guardar arrays:
[[i32; 3]; 2]é uma grade que você lê comgrid[linha][coluna]. - Se precisar mudar o tamanho, use um
Vec.
Teste o que aprendeu
Seção intitulada “Teste o que aprendeu”Teste o que aprendeu
1. O que é verdade sobre o tamanho de um array em Rust?
2. O que acontece quando você acessa um índice fora dos limites do array em tempo de execução?
3. O que let zeros = [0; 5]; cria?
Pontuação: 0 / 3
Para saber mais
Seção intitulada “Para saber mais”- The Array Type — The Rust Book (em inglês): a introdução oficial aos arrays, incluindo por que o tamanho faz parte do tipo.
- Arrays and Slices — Rust by Example (em inglês): exemplos curtos e executáveis, além de um primeiro contato com slices.
- Looping Through a Collection with
for— The Rust Book (em inglês): por que um laçoforé mais seguro do que percorrer um array com um índice. array— documentação da std (em inglês): o que os arrays sabem fazer, comomapeas_slice, e como eles também aproveitam todos os métodos de slices.