Como obter uma fatia como array em Rust: do iniciante ao guru

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Fatia como array em Rust: por que é difícil e como fazer corretamente

\n\n

Todo mundo que escreveu em Rust por mais de alguns dias já enfrentou a situação frustrante: você tem um &[u8] (fatia), mas a função precisa de um [u8; 4] (array). Em C, você simplesmente pegaria um ponteiro. Em Python, fatiaria. Em Rust... começa a dança complicada. Mas não se assuste — por trás dessa complexidade está uma segurança genial.

\n\n

Neste artigo, vamos abordar como obter uma fatia como array em Rust de todas as formas possíveis: do "rápido e sujo" ao "correto e confiável". Você aprenderá por que o Rust não permite simplesmente transformar uma fatia em um array e como contornar esse "problema" com máximo desempenho.

\n\n

Por que o Rust não permite simplesmente copiar uma fatia para um array?

\n\n

Imagine: você pede uma pizza inteira e recebem um pedaço. Você diz: "Isso é parte da pizza, faça dela uma inteira". Assim é com a fatia — ela é uma referência a parte dos dados, enquanto o array é um tipo proprietário de tamanho fixo. O tamanho do array é conhecido em tempo de compilação, enquanto o tamanho da fatia é conhecido apenas em tempo de execução.

\n\n

Portanto, simplesmente escrever let arr: [u8; 4] = slice não funciona. O compilador dirá: "Desculpe, não sei se sua fatia cabe em um array de 4 elementos". O Rust coloca a segurança acima de tudo — se a fatia for mais curta, você terá lixo ou pânico.

\n\n

Método 1: try_into() — método moderno e seguro

\n\n

A partir do Rust 1.47, surgiu uma maneira elegante através da trait TryInto. Este é o método recomendado para converter uma fatia em array. Ele retorna um Result, então você sempre saberá se a conversão foi bem-sucedida.

\n\n
use std::convert::TryInto;\n\nfn main() {\n    let slice: &[u8] = &[10, 20, 30, 40, 50];\n    \n    // Tentamos obter um array de 3 elementos\n    let result: Result<[u8; 3], _> = slice[..3].try_into();\n    \n    match result {\n        Ok(arr) => println!("Array: {:?}", arr),\n        Err(_) => println!("Elementos insuficientes!"),\n    }\n    \n    // Ou simplesmente usamos unwrap se tivermos certeza\n    let arr: [u8; 4] = slice[..4].try_into().unwrap();\n    println!("Array de 4: {:?}", arr);\n}
\n\n

Como funciona? O método try_into() verifica o comprimento da fatia em tempo de execução. Se o comprimento corresponder, ele converte; caso contrário, retorna um erro. Esta é a solução ideal para 99% dos casos.

\n\n

Método 2: copy_from_slice() — para quem gosta de controle

\n\n

Se você já tem um array (por exemplo, inicializado com zeros), pode copiar os dados da fatia. Este método exige que a fatia não seja mais curta que o array — caso contrário, ocorrerá pânico.

\n\n
fn main() {\n    let slice: &[u32] = &[100, 200, 300];\n    let mut arr: [u32; 3] = [0; 3]; // criamos um array vazio\n    \n    arr.copy_from_slice(slice);\n    println!("Copiado: {:?}", arr);\n    \n    // Se a fatia for mais longa — pegue um subconjunto\n    let long_slice = &[1, 2, 3, 4, 5];\n    let mut small_arr = [0u8; 2];\n    small_arr.copy_from_slice(&long_slice[..2]);\n    println!("Parte da fatia: {:?}", small_arr);\n}
\n\n

Importante: copy_from_slice funciona apenas para tipos que implementam Copy (por exemplo, números). Para strings, use clone_from_slice.

\n\n

Método 3: Iteração manual — para radicais

\n\n

Às vezes, é necessário fazer algo não padrão. Por exemplo, converter uma fatia alterando a ordem ou filtrando. Nesse caso, pode-se iterar manualmente:

\n\n
fn slice_to_array<T: Copy, const N: usize>(slice: &[T]) -> Option<[T; N]> {\n    if slice.len() != N {\n        return None;\n    }\n    \n    let mut arr = [unsafe { std::mem::zeroed() }; N];\n    for (i, &val) in slice.iter().enumerate() {\n        arr[i] = val;\n    }\n    Some(arr)\n}\n\nfn main() {\n                

Blogs

Book Recommendations