<h2>Entendendo Slices em Rust</h2>
<p>Um slice é uma <strong>referência a uma parte contígua de uma coleção</strong>, como um array ou string. Diferentemente de um vetor, que possui tamanho dinâmico e é dono dos dados, um slice é apenas uma "janela" para dados que já existem, sem transferir propriedade. Isso torna slices incrivelmente eficientes para passar partes de dados sem copiar ou alocar memória adicional.</p>
<p>Em Rust, quando você trabalha com slices, está lidando com dois conceitos fundamentais: um <strong>ponteiro para o primeiro elemento</strong> e um <strong>comprimento</strong>. A linguagem garante através do seu sistema de empréstimo que essas referências são sempre válidas. Você encontrará slices em praticamente todo código Rust profissional, seja ao processar strings, arrays ou vetores.</p>
<h2>Sintaxe e Tipos de Slices</h2>
<h3>Slices de Arrays e Vetores</h3>
<p>A sintaxe básica para criar um slice é usar a notação de intervalo <code>[início..fim]</code>. O índice inicial é inclusivo, enquanto o final é exclusivo:</p>
<pre><code class="language-rust">fn main() {
let numeros = vec![10, 20, 30, 40, 50];
// Slice do índice 1 ao 3 (não inclui 3)
let slice: &[i32] = &numeros[1..3];
println!("{:?}", slice); // [20, 30]
// Do início até índice 2
let inicio = &numeros[..2];
println!("{:?}", inicio); // [10, 20]
// Do índice 2 até o final
let fim = &numeros[2..];
println!("{:?}", fim); // [30, 40, 50]
// Slice inteiro
let tudo = &numeros[..];
println!("{:?}", tudo); // [10, 20, 30, 40, 50]
}</code></pre>
<p>A anotação de tipo <code>&[i32]</code> representa uma referência a um slice de inteiros de 32 bits. Note que o tamanho não está especificado no tipo — isso é exatamente o ponto: slices têm tamanho dinâmico em tempo de compilação.</p>
<h3>String Slices</h3>
<p>String slices (<code>&str</code>) são particularmente importantes em Rust. Eles representam uma sequência válida de UTF-8 bytes. Uma string literal já é um slice:</p>
<pre><code class="language-rust">fn main() {
let mensagem = "Olá, Rust!";
let tipo: &str = mensagem; // Automaticamente um slice
// Extraindo parte da string
let parte = &mensagem[0..3];
println!("{}", parte); // "Olá"
// Função que aceita um slice de string
processar_texto(&mensagem);
processar_texto("String literal");
}
fn processar_texto(texto: &str) {
println!("Recebido: {}", texto);
}</code></pre>
<p>Quando você passa uma <code>String</code> para uma função que espera <code>&str</code>, Rust converte automaticamente — isso é chamado <strong>coerção de tipo</strong>. Essa flexibilidade é um dos grandes poderes do design de slices.</p>
<h2>O Sistema de Empréstimo e Segurança</h2>
<h3>Garantias de Segurança</h3>
<p>Slices funcionam em harmonia perfeita com o sistema de propriedade e empréstimo de Rust. Enquanto uma referência a um slice está ativa, os dados subjacentes não podem ser modificados (se você possui uma referência imutável) nem movidos. Isso previne <strong>dangling pointers</strong> — um problema clássico de linguagens como C:</p>
<pre><code class="language-rust">fn main() {
let mut vetor = vec![1, 2, 3, 4, 5];
let slice = &vetor[1..3]; // Empréstimo imutável
// Isto causaria erro de compilação:
// vetor.push(6); // Não pode modificar enquanto slice existe
println!("{:?}", slice); // [2, 3]
// Após sair do escopo de 'slice', posso modificar novamente
vetor.push(6);
println!("{:?}", vetor);
}</code></pre>
<p>Se você precisar modificar os dados, use um slice mutável. Mas lembre-se: apenas <strong>uma referência mutável</strong> pode existir por vez:</p>
<pre><code class="language-rust">fn main() {
let mut vetor = vec![10, 20, 30];
let slice_mut = &mut vetor[0..2];
slice_mut[0] = 15; // Modificação via slice mutável
println!("{:?}", vetor); // [15, 20, 30]
}</code></pre>
<h2>Padrões Práticos com Slices</h2>
<h3>Funções que Trabalham com Partes de Dados</h3>
<p>Slices são perfeitos para escrever funções genéricas que funcionam com qualquer tamanho de dados. Aqui está um exemplo prático — uma função que encontra a soma dos números em um slice:</p>
<pre><code class="language-rust">fn soma_slice(numeros: &[i32]) -> i32 {
numeros.iter().sum()
}
fn maior_elemento(slice: &[i32]) -> Option<i32> {
if slice.is_empty() {
None
} else {
Some(*slice.iter().max().unwrap())
}
}
fn main() {
let arr = [1, 2, 3, 4, 5];
let vetor = vec![10, 20, 30];
// Funciona com arrays
println!("Soma: {}", soma_slice(&arr));
// Funciona com vetores (convertidos para slices)
println!("Soma: {}", soma_slice(&vetor));
// Funciona com partes específicas
println!("Maior: {:?}", maior_elemento(&arr[1..4]));
}</code></pre>
<h3>Iteração Eficiente</h3>
<p>Slices trabalham perfeitamente com iteradores, sem necessidade de copiar dados:</p>
<pre><code class="language-rust">fn filtrar_pares(numeros: &[i32]) -> Vec<i32> {
numeros
.iter()
.filter(|n| *n % 2 == 0)
.copied()
.collect()
}
fn main() {
let dados = vec![1, 2, 3, 4, 5, 6];
let pares = filtrar_pares(&dados);
println!("{:?}", pares); // [2, 4, 6]
}</code></pre>
<h2>Conclusão</h2>
<p>Slices são um pilar do Rust moderno. Eles oferecem três benefícios fundamentais que você deve internalizar: <strong>(1) segurança de memória</strong> garantida pelo compilador através do sistema de empréstimo; <strong>(2) eficiência</strong> permitindo trabalhar com partes de dados sem copiar ou alocar; e <strong>(3) flexibilidade</strong> permitindo escrever funções que funcionam com arrays, vetores e strings de forma uniforme. Domine slices e você entenderá o coração do design de Rust.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://doc.rust-lang.org/book/ch04-03-slices.html" target="_blank" rel="noopener noreferrer">The Rust Book - Understanding Ownership</a></li>
<li><a href="https://doc.rust-lang.org/rust-by-example/primitives/array.html" target="_blank" rel="noopener noreferrer">Rust by Example - Slices</a></li>
<li><a href="https://doc.rust-lang.org/std/primitive.slice.html" target="_blank" rel="noopener noreferrer">Rust Standard Library Documentation - slice</a></li>
<li><a href="https://github.com/rust-lang/rustlings" target="_blank" rel="noopener noreferrer">Rustlings - Exercises for Learning Rust</a></li>
</ul>