---
title: "Slices (\u0026[T]) em Rust"
url: "https://rustlang.com.br/stdlib/slice/"
markdown_url: "https://rustlang.com.br/stdlib/slice.MD"
description: "Guia completo de slices (\u0026[T]) em Rust: criação, indexação, iteração, windows, chunks, split, binary_search, sort e padrões práticos."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Slices (&[T]) em Rust

Guia completo de slices (&[T]) em Rust: criação, indexação, iteração, windows, chunks, split, binary_search, sort e padrões práticos.


## O que são Slices

Um slice (`&[T]`) é uma **referência** a uma sequência contígua de elementos do tipo `T`. Ele não possui os dados — apenas aponta para eles. Internamente, um slice é composto por dois valores: um ponteiro para o primeiro elemento e um comprimento. Essa representação simples permite que slices referenciem partes de arrays, vetores, ou qualquer bloco de memória contíguo.

Slices são fundamentais em Rust porque permitem trabalhar com sequências de dados de forma genérica, sem se preocupar se a origem é um array `[T; N]`, um `Vec<T>`, ou outra estrutura. Ao aceitar `&[T]` como parâmetro de função (em vez de `&Vec<T>`), seu código se torna mais flexível e idiomático. A versão mutável `&mut [T]` permite modificar os elementos sem realocar.

---

## Criando Slices

```rust
fn main() {
    // A partir de um array
    let array = [10, 20, 30, 40, 50];
    let slice_completo: &[i32] = &array;         // Todo o array
    let parcial: &[i32] = &array[1..4];          // [20, 30, 40]
    let do_inicio: &[i32] = &array[..3];         // [10, 20, 30]
    let ate_final: &[i32] = &array[2..];         // [30, 40, 50]

    // A partir de um Vec
    let vec = vec![1, 2, 3, 4, 5];
    let slice_vec: &[i32] = &vec;                // Coerção automática
    let parte: &[i32] = &vec[1..3];              // [2, 3]

    // Slice mutável
    let mut dados = vec![5, 3, 1, 4, 2];
    let slice_mut: &mut [i32] = &mut dados;
    slice_mut.sort();
    println!("Ordenado: {slice_mut:?}"); // [1, 2, 3, 4, 5]

    // Slice vazio
    let vazio: &[i32] = &[];

    // A partir de uma String (slice de bytes)
    let texto = String::from("Rust");
    let bytes: &[u8] = texto.as_bytes();

    println!("{slice_completo:?} | {parcial:?} | {do_inicio:?} | {ate_final:?}");
    println!("{slice_vec:?} | {parte:?} | {vazio:?} | {bytes:?}");
}
```

---

## Tabela de Métodos Principais

| Método | Descrição | Exemplo |
|---|---|---|
| `len()` | Número de elementos | `s.len()` → `5` |
| `is_empty()` | Verifica se está vazio | `s.is_empty()` |
| `first()` | Primeiro elemento (`Option<&T>`) | `s.first()` → `Some(&1)` |
| `last()` | Último elemento (`Option<&T>`) | `s.last()` → `Some(&5)` |
| `get(i)` | Acesso seguro por índice | `s.get(2)` → `Some(&3)` |
| `contains(&val)` | Verifica se contém o valor | `s.contains(&3)` → `true` |
| `starts_with(sub)` | Verifica se começa com o subslice | `s.starts_with(&[1, 2])` |
| `ends_with(sub)` | Verifica se termina com o subslice | `s.ends_with(&[4, 5])` |
| `iter()` | Iterador de `&T` | `s.iter()` |
| `iter_mut()` | Iterador de `&mut T` | `s.iter_mut()` |
| `windows(n)` | Janelas deslizantes de tamanho `n` | `s.windows(3)` |
| `chunks(n)` | Pedaços de tamanho `n` | `s.chunks(2)` |
| `chunks_exact(n)` | Pedaços exatos (descarta resto) | `s.chunks_exact(3)` |
| `split(f)` | Divide onde `f` é true | `s.split(\|x\| *x == 0)` |
| `splitn(n, f)` | Divide em no máximo `n` partes | `s.splitn(2, \|x\| *x == 0)` |
| `split_at(i)` | Divide em dois slices na posição `i` | `s.split_at(3)` |
| `sort()` | Ordena in-place (requer `&mut [T]`) | `s.sort()` |
| `sort_by(f)` | Ordena com comparador | `s.sort_by(\|a, b\| b.cmp(a))` |
| `sort_unstable()` | Ordena (pode ser mais rápido) | `s.sort_unstable()` |
| `binary_search(&val)` | Busca binária (requer slice ordenado) | `s.binary_search(&5)` |
| `reverse()` | Inverte in-place | `s.reverse()` |
| `swap(i, j)` | Troca elementos nas posições i e j | `s.swap(0, 2)` |
| `rotate_left(n)` | Rotaciona para a esquerda | `s.rotate_left(2)` |
| `fill(val)` | Preenche com um valor | `s.fill(0)` |
| `copy_from_slice(src)` | Copia de outro slice (mesmo tamanho) | `dest.copy_from_slice(src)` |
| `to_vec()` | Cria um `Vec<T>` a partir do slice | `s.to_vec()` |
| `concat()` | Concatena slices aninhados | `[&[1,2], &[3,4]].concat()` |
| `join(sep)` | Junta com separador | Disponível para `&[&str]` etc. |

---

## Exemplos Práticos

### 1. Processamento com windows e chunks

```rust
fn media_movel(dados: &[f64], janela: usize) -> Vec<f64> {
    dados
        .windows(janela)
        .map(|w| w.iter().sum::<f64>() / w.len() as f64)
        .collect()
}

fn processar_em_lotes(dados: &[i32], tamanho_lote: usize) {
    for (i, lote) in dados.chunks(tamanho_lote).enumerate() {
        let soma: i32 = lote.iter().sum();
        let media = soma as f64 / lote.len() as f64;
        println!("Lote {}: {:?} (média: {media:.1})", i + 1, lote);
    }
}

fn main() {
    let precos = vec![100.0, 105.0, 98.0, 110.0, 107.0, 115.0, 112.0];
    let medias = media_movel(&precos, 3);
    println!("Médias móveis (3): {medias:.1?}");

    println!();

    let dados: Vec<i32> = (1..=15).collect();
    processar_em_lotes(&dados, 4);
}
```

### 2. Busca Binária em Dados Ordenados

```rust
fn main() {
    let dados = vec![2, 5, 8, 12, 16, 23, 38, 56, 72, 91];

    // binary_search retorna Result<usize, usize>
    // Ok(indice) se encontrado, Err(indice_insercao) se não
    match dados.binary_search(&23) {
        Ok(pos) => println!("23 encontrado na posição {pos}"),     // posição 5
        Err(pos) => println!("23 não encontrado, inserir em {pos}"),
    }

    match dados.binary_search(&15) {
        Ok(pos) => println!("15 encontrado na posição {pos}"),
        Err(pos) => println!("15 não encontrado, inserir em {pos}"), // posição 4
    }

    // binary_search_by para tipos customizados
    let nomes = vec!["Ana", "Bruno", "Carlos", "Diana", "Eduardo"];
    match nomes.binary_search_by(|probe| probe.cmp(&"Carlos")) {
        Ok(pos) => println!("Carlos na posição {pos}"),
        Err(_) => println!("Não encontrado"),
    }

    // Inserir mantendo a ordem
    let mut ordenado = vec![1, 3, 5, 7, 9];
    let novo = 6;
    let pos = ordenado.binary_search(&novo).unwrap_or_else(|x| x);
    ordenado.insert(pos, novo);
    println!("Após inserir {novo}: {ordenado:?}"); // [1, 3, 5, 6, 7, 9]
}
```

### 3. split e Padrões de Divisão

```rust
fn main() {
    let dados = [1, 0, 2, 3, 0, 4, 5, 6, 0, 7];

    // split — divide onde o predicado é verdadeiro
    println!("Split por zeros:");
    for grupo in dados.split(|x| *x == 0) {
        println!("  {grupo:?}");
    }
    // [1], [2, 3], [4, 5, 6], [7]

    // splitn — limita o número de divisões
    println!("\nSplit (máx 2 partes):");
    for grupo in dados.splitn(2, |x| *x == 0) {
        println!("  {grupo:?}");
    }
    // [1], [2, 3, 0, 4, 5, 6, 0, 7]

    // split_at — divide em posição específica
    let numeros = [10, 20, 30, 40, 50];
    let (esquerda, direita) = numeros.split_at(3);
    println!("\nEsquerda: {esquerda:?}"); // [10, 20, 30]
    println!("Direita: {direita:?}");     // [40, 50]

    // rsplit — divide da direita para a esquerda
    println!("\nRsplit por zeros:");
    for grupo in dados.rsplit(|x| *x == 0) {
        println!("  {grupo:?}");
    }
    // [7], [4, 5, 6], [2, 3], [1]
}
```

### 4. Funções Genéricas que Aceitam Slices

```rust
fn encontrar_maximo<T: PartialOrd>(slice: &[T]) -> Option<&T> {
    slice.iter().reduce(|max, x| if x > max { x } else { max })
}

fn estatisticas(dados: &[f64]) -> Option<(f64, f64, f64)> {
    if dados.is_empty() {
        return None;
    }

    let soma: f64 = dados.iter().sum();
    let media = soma / dados.len() as f64;

    let variancia = dados.iter()
        .map(|x| (x - media).powi(2))
        .sum::<f64>() / dados.len() as f64;

    let desvio_padrao = variancia.sqrt();

    Some((media, variancia, desvio_padrao))
}

fn imprimir_tabela(cabecalho: &[&str], dados: &[&[&str]]) {
    // Calcular largura de cada coluna
    let larguras: Vec<usize> = (0..cabecalho.len())
        .map(|col| {
            let max_dados = dados.iter()
                .filter_map(|linha| linha.get(col))
                .map(|s| s.len())
                .max()
                .unwrap_or(0);
            cabecalho[col].len().max(max_dados)
        })
        .collect();

    // Imprimir cabeçalho
    for (i, h) in cabecalho.iter().enumerate() {
        print!("| {:<width$} ", h, width = larguras[i]);
    }
    println!("|");

    // Separador
    for w in &larguras {
        print!("|{}", "-".repeat(w + 2));
    }
    println!("|");

    // Dados
    for linha in dados {
        for (i, celula) in linha.iter().enumerate() {
            print!("| {:<width$} ", celula, width = larguras[i]);
        }
        println!("|");
    }
}

fn main() {
    // Aceita Vec, array ou slice — todos coercem para &[T]
    let vec = vec![3.2, 1.8, 4.5, 2.1, 3.7];
    let array = [10.0, 20.0, 30.0];

    println!("Max vec: {:?}", encontrar_maximo(&vec));    // Some(4.5)
    println!("Max array: {:?}", encontrar_maximo(&array)); // Some(30.0)

    if let Some((media, var, dp)) = estatisticas(&vec) {
        println!("Média: {media:.2}, Variância: {var:.2}, DP: {dp:.2}");
    }

    println!();

    let cabecalho = ["Nome", "Linguagem", "Nível"];
    let dados: Vec<&[&str]> = vec![
        &["Ana", "Rust", "Avançado"],
        &["Bruno", "Python", "Intermediário"],
        &["Carlos", "Go", "Iniciante"],
    ];
    imprimir_tabela(&cabecalho, &dados);
}
```

### 5. Operações In-Place com Slices Mutáveis

```rust
fn particionar<T: PartialOrd + Copy>(slice: &mut [T], pivot: T) -> usize {
    let mut i = 0;
    for j in 0..slice.len() {
        if slice[j] <= pivot {
            slice.swap(i, j);
            i += 1;
        }
    }
    i
}

fn main() {
    // sort_unstable — geralmente mais rápido que sort
    let mut numeros = vec![38, 27, 43, 3, 9, 82, 10];
    numeros.sort_unstable();
    println!("Ordenado: {numeros:?}");

    // sort_by_key — ordenar por critério
    let mut palavras = vec!["banana", "uva", "abacaxi", "kiwi", "maçã"];
    palavras.sort_by_key(|p| p.len());
    println!("Por tamanho: {palavras:?}");

    // reverse
    let mut seq = vec![1, 2, 3, 4, 5];
    seq.reverse();
    println!("Invertido: {seq:?}"); // [5, 4, 3, 2, 1]

    // rotate_left / rotate_right
    let mut fila = vec!["A", "B", "C", "D", "E"];
    fila.rotate_left(2);
    println!("Rotação esquerda: {fila:?}"); // ["C", "D", "E", "A", "B"]

    // fill — preencher com um valor
    let mut buffer = vec![0u8; 10];
    buffer[3..7].fill(0xFF);
    println!("Buffer: {buffer:?}");

    // swap
    let mut dados = vec![10, 20, 30, 40, 50];
    dados.swap(1, 3);
    println!("Após swap: {dados:?}"); // [10, 40, 30, 20, 50]

    // Particionar
    let mut vals = vec![7, 2, 9, 1, 5, 8, 3, 6, 4];
    let pos = particionar(&mut vals, 5);
    println!("Particionado (pivot=5): {vals:?}, posição: {pos}");
}
```

---

## Dicas de Performance e Armadilhas

1. **Prefira `&[T]` a `&Vec<T>` em parâmetros**: Aceitar `&[T]` torna sua função mais genérica — ela funciona com arrays, vetores e outros slices. `Vec<T>` implementa `Deref<Target=[T]>`, então a conversão é automática.

2. **Indexação pode causar panic**: `slice[i]` gera panic se `i >= slice.len()`. Use `slice.get(i)` para acesso seguro com `Option<&T>`.

3. **`sort_unstable` vs `sort`**: `sort_unstable()` é geralmente mais rápido e usa menos memória que `sort()`, mas não preserva a ordem de elementos iguais. Use `sort()` quando a estabilidade importa.

4. **`chunks_exact` descarta o resto**: Se o tamanho do slice não é múltiplo do tamanho do chunk, `chunks_exact` ignora os elementos restantes. Use `chunks_exact(n).remainder()` para acessar o que sobrou.

5. **Copy semântico com slices**: Slices são referências e, portanto, `Copy`. Passar `&[T]` é barato independente do tamanho — apenas um ponteiro e um comprimento são copiados.

6. **`split_at` para processamento paralelo**: Dividir um slice mutável em duas metades com `split_at_mut` permite processá-las em paralelo sem violar as regras de borrowing.

---

## Veja Também

- [Filtrar Vetores em Rust](/receitas/filtrar-vetor/) — receitas práticas de filtragem
- [Vec\<T\>: Vetor Dinâmico](/stdlib/vec/) — o tipo que mais produz slices
- [String e &str](/stdlib/string/) — `&str` é essencialmente um `&[u8]` com garantia UTF-8
- [Iterator Trait](/stdlib/iterator/) — slices fornecem iteradores nativos
- [Cow\<T\>: Clone on Write](/stdlib/cow/) — `Cow<[T]>` para slices com ownership flexível
- [Cheatsheet Rust](/cheatsheet/) — referência rápida de sintaxe
- [Documentação oficial — primitive slice](https://doc.rust-lang.org/std/primitive.slice.html)
