---
title: "Arrays e [T; N] em Rust"
url: "https://rustlang.com.br/stdlib/arrays/"
markdown_url: "https://rustlang.com.br/stdlib/arrays.MD"
description: "Guia completo de arrays em Rust: [T; N] com tamanho fixo, alocação na stack, indexação, iteração, map, from_fn, const generics e comparação com Vec e slices."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Arrays e [T; N] em Rust

Guia completo de arrays em Rust: [T; N] com tamanho fixo, alocação na stack, indexação, iteração, map, from_fn, const generics e comparação com Vec e slices.


Um **array** em Rust, escrito como `[T; N]`, é uma coleção de tamanho fixo com `N` elementos do tipo `T`. Diferente do `Vec`, o tamanho do array é conhecido em tempo de compilação e faz parte do seu tipo. Arrays são alocados na **stack** (quando declarados como variáveis locais), o que os torna extremamente rápidos para acessar e iterar.

## Quando Usar Arrays

Use arrays quando:

- O **tamanho é conhecido em tempo de compilação** e não muda.
- Precisa de **alocação na stack** (sem heap) para máxima performance.
- Trabalha com dados de tamanho fixo: coordenadas, pixels, buffers de tamanho conhecido.
- Quer **garantia em tempo de compilação** de que o tamanho está correto.

Se o tamanho pode variar em tempo de execução, use [`Vec<T>`](/stdlib/vec/). Para referências a sequências de tamanho variável, use [slices (`&[T]`)](/stdlib/slice/).

## Criando e Inicializando

```rust
fn main() {
    // Tipo explícito: [T; N]
    let numeros: [i32; 5] = [1, 2, 3, 4, 5];

    // Tipo inferido pelo compilador
    let nomes = ["Ana", "Bruno", "Carla"];

    // Inicializar todos os elementos com o mesmo valor
    let zeros = [0u8; 1024]; // 1024 bytes, todos zero
    let tracos = ['-'; 40]; // 40 caracteres '-'

    // Usando std::array::from_fn para inicialização computada
    let quadrados: [i32; 10] = std::array::from_fn(|i| (i as i32 + 1).powi(2));
    println!("Quadrados: {:?}", quadrados);
    // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

    // Array de structs
    #[derive(Debug)]
    struct Ponto { x: f64, y: f64 }

    let pontos: [Ponto; 3] = [
        Ponto { x: 0.0, y: 0.0 },
        Ponto { x: 1.0, y: 2.0 },
        Ponto { x: 3.0, y: 4.0 },
    ];
    println!("{:?}", pontos);

    println!("Tamanho de numeros: {}", numeros.len());
    println!("Traços: {}", tracos.iter().collect::<String>());
}
```

## Tabela de Métodos e Operações

| Operação | Descrição | Complexidade |
|---|---|---|
| `arr[i]` | Acesso por índice (com verificação de limites) | O(1) |
| `arr.len()` | Número de elementos | O(1) |
| `arr.is_empty()` | Verifica se o array tem tamanho 0 | O(1) |
| `arr.iter()` | Iterador sobre referências `&T` | O(n) |
| `arr.iter_mut()` | Iterador sobre referências mutáveis `&mut T` | O(n) |
| `arr.into_iter()` | Iterador que consome o array (move os elementos) | O(n) |
| `arr.map(f)` | Aplica função a cada elemento, retorna novo array | O(n) |
| `arr.each_ref()` | Converte `&[T; N]` em `[&T; N]` | O(n) |
| `arr.each_mut()` | Converte `&mut [T; N]` em `[&mut T; N]` | O(n) |
| `arr.contains(&v)` | Verifica se contém o valor (via slice) | O(n) |
| `arr.sort()` | Ordena in-place (via slice) | O(n log n) |
| `arr.reverse()` | Inverte a ordem (via slice) | O(n) |
| `arr.windows(n)` | Janelas deslizantes (via slice) | O(n) |
| `arr.chunks(n)` | Divide em pedaços (via slice) | O(n) |
| `std::array::from_fn(f)` | Cria array com função de índice | O(n) |

## Exemplos Práticos

### 1. Indexação e Iteração

```rust
fn main() {
    let meses = [
        "Janeiro", "Fevereiro", "Março", "Abril",
        "Maio", "Junho", "Julho", "Agosto",
        "Setembro", "Outubro", "Novembro", "Dezembro",
    ];

    // Acesso por índice
    println!("Primeiro mês: {}", meses[0]);
    println!("Último mês: {}", meses[11]);

    // Acesso seguro com get() (retorna Option)
    match meses.get(5) {
        Some(mes) => println!("Mês 6: {}", mes),
        None => println!("Índice inválido"),
    }

    // Iteração com enumerate
    println!("\nCalendário:");
    for (i, mes) in meses.iter().enumerate() {
        println!("  {:2}. {}", i + 1, mes);
    }

    // into_iter consome o array (move os elementos)
    let cores = ["vermelho", "verde", "azul"];
    for cor in cores {
        // Em Rust 2021+, `for x in array` usa IntoIterator
        println!("Cor: {}", cor);
    }
}
```

### 2. map e Transformações

```rust
fn main() {
    let temperaturas_c = [0.0_f64, 20.0, 37.0, 100.0];

    // map: transforma cada elemento, retornando novo array do mesmo tamanho
    let temperaturas_f = temperaturas_c.map(|c| c * 9.0 / 5.0 + 32.0);
    println!("Celsius:    {:?}", temperaturas_c);
    println!("Fahrenheit: {:?}", temperaturas_f);

    // Converter array de strings para array de tamanhos
    let palavras = ["Rust", "é", "incrível"];
    let tamanhos = palavras.map(|p| p.len());
    println!("Tamanhos: {:?}", tamanhos); // [4, 2, 9]

    // from_fn: criar array com lógica complexa
    let fibonacci: [u64; 10] = std::array::from_fn(|i| {
        if i < 2 {
            return i as u64;
        }
        let mut a = 0u64;
        let mut b = 1u64;
        for _ in 2..=i {
            let temp = a + b;
            a = b;
            b = temp;
        }
        b
    });
    println!("Fibonacci: {:?}", fibonacci);
    // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
}
```

### 3. Arrays como Slices e Métodos de Slice

```rust
fn main() {
    let mut numeros = [5, 3, 8, 1, 9, 2, 7, 4, 6];

    // Arrays implementam Deref<Target=[T]>, então métodos de slice funcionam
    println!("Contém 7? {}", numeros.contains(&7)); // true
    println!("Começa com [5, 3]? {}", numeros.starts_with(&[5, 3])); // true

    // Ordenar (modifica in-place via slice)
    numeros.sort();
    println!("Ordenado: {:?}", numeros); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

    // Reverter
    numeros.reverse();
    println!("Reverso: {:?}", numeros); // [9, 8, 7, 6, 5, 4, 3, 2, 1]

    // Janelas deslizantes
    let dados = [10, 20, 30, 40, 50];
    println!("\nJanelas de tamanho 3:");
    for janela in dados.windows(3) {
        let media: f64 = janela.iter().sum::<i32>() as f64 / 3.0;
        println!("  {:?} -> média = {:.1}", janela, media);
    }

    // Fatias (slices) de arrays
    let primeiros_tres = &dados[..3];
    let ultimos_dois = &dados[3..];
    println!("\nPrimeiros 3: {:?}", primeiros_tres);
    println!("Últimos 2: {:?}", ultimos_dois);
}
```

### 4. Const Generics — Funções Genéricas sobre Tamanho

```rust
// Função genérica que aceita arrays de qualquer tamanho
fn soma<const N: usize>(arr: &[f64; N]) -> f64 {
    arr.iter().sum()
}

fn media<const N: usize>(arr: &[f64; N]) -> f64 {
    soma(arr) / N as f64
}

fn imprimir_array<T: std::fmt::Debug, const N: usize>(arr: &[T; N]) {
    println!("[{}] {:?}", N, arr);
}

fn main() {
    let notas_3 = [8.5, 9.0, 7.5];
    let notas_5 = [8.0, 9.5, 7.0, 8.5, 6.5];

    // A mesma função funciona para arrays de tamanhos diferentes
    println!("Soma (3 notas): {:.1}", soma(&notas_3));
    println!("Média (3 notas): {:.2}", media(&notas_3));
    println!("Soma (5 notas): {:.1}", soma(&notas_5));
    println!("Média (5 notas): {:.2}", media(&notas_5));

    imprimir_array(&[1, 2, 3]);
    imprimir_array(&["a", "b", "c", "d"]);
}
```

### 5. Padrões Comuns com Arrays

```rust
fn main() {
    // Desestruturação
    let rgb = [255u8, 128, 0];
    let [r, g, b] = rgb;
    println!("R={}, G={}, B={}", r, g, b);

    // Comparação (arrays implementam PartialEq)
    let a = [1, 2, 3];
    let b = [1, 2, 3];
    let c = [1, 2, 4];
    println!("a == b? {}", a == b); // true
    println!("a == c? {}", a == c); // false

    // Array bidimensional (matriz)
    let matriz: [[f64; 3]; 3] = [
        [1.0, 0.0, 0.0],
        [0.0, 1.0, 0.0],
        [0.0, 0.0, 1.0],
    ];

    println!("\nMatriz identidade 3x3:");
    for linha in &matriz {
        println!("  {:?}", linha);
    }

    // Converter array em Vec
    let arr = [10, 20, 30];
    let vec: Vec<i32> = arr.into(); // ou arr.to_vec()
    println!("\nVec: {:?}", vec);

    // Tentar converter slice em array
    let slice: &[i32] = &[1, 2, 3];
    let arr: [i32; 3] = slice.try_into().expect("slice com tamanho errado");
    println!("Array de slice: {:?}", arr);

    // Usar array como buffer fixo
    let mut buffer = [0u8; 256];
    let mensagem = b"Ola, Rust!";
    buffer[..mensagem.len()].copy_from_slice(mensagem);
    println!(
        "Buffer: {}",
        std::str::from_utf8(&buffer[..mensagem.len()]).unwrap()
    );
}
```

## Características de Desempenho

| Operação | Array `[T; N]` | Vec`<T>` | Slice `&[T]` |
|---|---|---|---|
| Alocação | Stack | Heap | Referência |
| Tamanho em runtime | Fixo (compilação) | Dinâmico | Dinâmico |
| Acesso por índice | O(1) | O(1) | O(1) |
| Overhead de memória | 0 bytes | 24 bytes (ptr+len+cap) | 16 bytes (ptr+len) |
| Cache-friendly | Sim | Sim | Sim |
| Crescimento | Impossível | `push()` O(1) amort. | Impossível |

**Memória:** Arrays são alocados diretamente na stack frame da função (quando são variáveis locais). Isso significa zero overhead de alocação, mas cuidado: arrays muito grandes na stack podem causar **stack overflow**. Para arrays grandes (dezenas de KB ou mais), considere usar `Vec` ou `Box<[T; N]>`.

**Tamanho do tipo:** O tamanho de `[T; N]` é exatamente `N * size_of::<T>()` bytes. Por exemplo, `[i32; 100]` ocupa 400 bytes na stack.

## Arrays vs Vec vs Slices

| Critério | `[T; N]` | `Vec<T>` | `&[T]` |
|---|---|---|---|
| Tamanho | Fixo (compilação) | Dinâmico | Dinâmico |
| Alocação | Stack | Heap | Referência |
| Pode crescer | Nao | Sim | Nao |
| Tipo de ownership | Owned | Owned | Borrowed |
| Uso típico | Buffers fixos, coords | Listas dinâmicas | Parâmetros de função |
| Coerção para slice | `&arr` -> `&[T]` | `&vec` -> `&[T]` | Já é slice |

**Regra prática:** Use arrays quando o tamanho é fixo e conhecido. Use `Vec` quando precisa de tamanho dinâmico. Use `&[T]` como parâmetro de função para aceitar tanto arrays quanto vetores.

```rust
// Função que aceita qualquer sequência (array, Vec, slice)
fn processar(dados: &[i32]) {
    println!("Processando {} elementos", dados.len());
}

fn main() {
    let array = [1, 2, 3];
    let vetor = vec![4, 5, 6];

    processar(&array);   // array -> &[i32]
    processar(&vetor);   // Vec -> &[i32]
    processar(&[7, 8]);  // slice literal
}
```

## Veja Também

- [Slices em Rust](/stdlib/slice/) --- fatias de tamanho dinâmico
- [Vec em Rust](/stdlib/vec/) --- vetor dinâmico alocado no heap
- [Tuplas em Rust](/stdlib/tuplas/) --- outro tipo de tamanho fixo com tipos heterogêneos
- [Ranges em Rust](/stdlib/ranges/) --- faixas para indexação e iteração
- [Variáveis, Tipos e Funções](/tutoriais/variaveis-tipos-funcoes/) --- fundamentos dos tipos em Rust
- [Filtrar Vetor em Rust](/receitas/filtrar-vetor/) --- técnicas de filtragem aplicáveis a slices
