Pular para o conteúdo

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.

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.

▶ Experimente você mesmo

Você também pode deixar o Rust deduzir o tipo e escrever só os valores:

let numbers = [1, 2, 3, 4, 5];

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);
}
▶ Experimente você mesmo

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());
}
▶ Experimente você mesmo

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 10

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

fn main() {
let numbers = [10, 20, 30];
for n in numbers {
println!("{n}");
}
}
▶ Experimente você mesmo

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: 21
▶ Experimente você mesmo

grid[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.

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.

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: 108
Média: 18.00
▶ Experimente você mesmo

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

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: 31
▶ Experimente você mesmo

Começ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ê com grid[linha][coluna].
  • Se precisar mudar o tamanho, use um Vec.

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