Fatias de Vec<T> em Rust: como funciona e por que você precisa disso?
\n\nSe você já programou em Rust e se perguntou "How do I get a slice of a Vec<T> in Rust?" — você não está sozinho. Esta é uma das perguntas mais populares no Stack Overflow, com milhares de visualizações. E não é à toa: trabalhar com vetores e suas fatias é uma habilidade fundamental, sem a qual nenhum projeto sério em Rust pode ser imaginado.
\n\nNeste artigo, não vamos apenas mostrar como obter uma fatia. Vamos analisar as melhores práticas de 2025, aprender a evitar armadilhas comuns e entender por que o Rust nos faz pensar tanto sobre empréstimos. Vamos lá!
\n\nO que é uma fatia (slice) em Rust?
\n\nAntes de pegar uma fatia, vamos entender o que é. Uma fatia é uma referência a uma sequência contígua de elementos na memória. Em Rust, uma fatia é denotada como &[T]. Não é uma estrutura de dados proprietária — ela apenas "olha" para uma parte dos dados que pertencem a outra pessoa (por exemplo, um vetor ou array).
A principal vantagem das fatias é a segurança. O compilador Rust garante que você não ultrapassará os limites da memória, e o sistema de empréstimo não permitirá que você modifique os dados enquanto houver referências ativas a eles.
\n\nPor que não usar o vetor diretamente?
\n\nUm vetor (Vec<T>) é uma estrutura proprietária. Se você o passar para uma função, ou o move (perdendo o acesso) ou passa uma referência. As fatias oferecem flexibilidade: você pode passar apenas uma parte dos dados, sem copiá-los e sem perder o controle sobre o vetor original.
Por exemplo, você está trabalhando com um grande conjunto de dados e deseja passar um fragmento dele para uma função de análise. A fatia é a ferramenta ideal: é leve (apenas duas palavras: ponteiro e comprimento) e segura.
\n\nPrincipais maneiras de obter uma fatia de Vec<T>
\n\nVamos à prática. Existem várias maneiras de obter uma fatia de um vetor. Veremos as mais populares e convenientes.
\n\n1. Operador de indexação: &vec[start..end]
\n\nA maneira mais direta é usar o operador de intervalo ..:
let vec = vec![1, 2, 3, 4, 5];\nlet slice: &[i32] = &vec[1..4]; // fatia do índice 1 ao 4 (excluindo o 4)\nprintln!("{:?}", slice); // [2, 3, 4]\n\nEste método usa verificação de limites em tempo de execução. Se você ultrapassar os limites do vetor, o programa entrará em pânico (panic). Para exemplos de aprendizado, isso é normal, mas em código de produção é preciso ter cuidado.
\n\nVocê pode usar várias formas de intervalos:
\n\n- \n
&vec[..]— o vetor inteiro \n&vec[2..]— do índice 2 até o final \n&vec[..3]— do início ao índice 3 (excluindo) \n&vec[1..=3]— do 1 ao 3 inclusive \n
2. Método .as_slice()
\n\nEste método retorna uma fatia do vetor inteiro. É mais seguro que &vec[..] porque expressa explicitamente a intenção:
let vec = vec![10, 20, 30];\nlet slice: &[i32] = vec.as_slice();\nprintln!("{:?}", slice); // [10, 20, 30]\n\nO método as_slice() é especialmente útil quando você quer enfatizar que está trabalhando com uma fatia, e não com um vetor. Isso torna o código mais legível e autodocumentado.
3. Obtendo uma fatia mutável: as_mut_slice()
\n\nSe você precisa modificar os elementos dentro da fatia (mas não o vetor em si), use as_mut_slice():
let mut vec = vec![1, 2, 3];\nlet slice: &mut [i32] = vec.as_mut_slice();\nslice[0] = 100;\nprintln!("{:?}", vec); // [100, 2, 3]\n\nObserve: o vetor deve ser declarado como mut. Além disso, você não pode ter simultaneamente fatias imutáveis e mutáveis — isso violaria as regras de empréstimo.