<h2>Vec<T>: Entendendo o Array Dinâmico Fundamental</h2>
<p>Vec<T> é a estrutura de dados mais versátil da Rust: um array alocado na heap que cresce e encolhe dinamicamente conforme necessário. Diferentemente de arrays primitivos como <code>[T; n]</code>, que têm tamanho fixo e conhecido em tempo de compilação, Vec permite que você trabalhe com coleções cujo tamanho é desconhecido ou muda durante a execução.</p>
<p>Internamente, Vec mantém três informações críticas: um ponteiro para os dados na heap, a capacidade (quantos elementos cabem sem realocação) e o comprimento (quantos elementos estão realmente armazenados). Essa distinção entre capacidade e comprimento é essencial para entender a performance e o comportamento de Vec.</p>
<pre><code class="language-rust">fn main() {
// Criando um Vec vazio
let mut numeros: Vec<i32> = Vec::new();
// Adicionando elementos
numeros.push(10);
numeros.push(20);
numeros.push(30);
println!("Vec: {:?}", numeros);
println!("Comprimento: {}", numeros.len());
println!("Capacidade: {}", numeros.capacity());
}</code></pre>
<h2>Criação, Inicialização e Operações Básicas</h2>
<p>Existem várias formas ergonômicas de criar um Vec em Rust. A macro <code>vec!</code> é a mais prática para inicializar com valores conhecidos, enquanto <code>Vec::new()</code> cria um vetor vazio. O método <code>with_capacity()</code> é crucial quando você sabe antecipadamente quantos elementos será necessário armazenar, evitando realocações desnecessárias.</p>
<pre><code class="language-rust">fn main() {
// Usando macro vec!
let mut cores = vec!["vermelho", "azul", "verde"];
// Pré-alocando capacidade
let mut dados: Vec<String> = Vec::with_capacity(100);
// Acessando elementos
println!("Primeira cor: {}", cores[0]);
// Iterando
for cor in &cores {
println!("{}", cor);
}
// Modificando
cores.push("amarelo");
cores[0] = "laranja";
// Removendo
let removido = cores.pop(); // Remove o último
println!("Removido: {:?}", removido);
}</code></pre>
<p>As operações de indexação usam <code>[]</code>, mas falham em runtime se o índice estiver fora dos limites. Para segurança, use <code>get()</code>, que retorna <code>Option<&T></code>. O método <code>pop()</code> remove e retorna o último elemento, enquanto <code>insert()</code> e <code>remove()</code> trabalham com índices específicos — porém são custosos para vetores grandes porque requerem realocação de memória.</p>
<h2>Propriedade, Empréstimo e Iteração Eficiente</h2>
<p>A relação entre Vec e o sistema de propriedade (ownership) de Rust é onde muitos iniciantes enfrentam dificuldades. Quando você passa um Vec para uma função sem usar referência, a propriedade é transferida e a variável original fica inacessível. Use <code>&vec</code> para empréstimos imutáveis e <code>&mut vec</code> para mutáveis.</p>
<pre><code class="language-rust">fn processar_vetor(vec: &[i32]) -> i32 {
vec.iter().sum()
}
fn duplicar_elementos(vec: &mut Vec<i32>) {
for elemento in vec.iter_mut() {
elemento = 2;
}
}
fn main() {
let mut numeros = vec![1, 2, 3, 4, 5];
let soma = processar_vetor(&numeros);
println!("Soma: {}", soma);
duplicar_elementos(&mut numeros);
println!("Duplicados: {:?}", numeros);
// Iteração eficiente com into_iter (consome o vetor)
let palavras = vec!["hello", "world"];
for palavra in palavras {
println!("{}", palavra);
}
// 'palavras' não está mais acessível aqui
}</code></pre>
<p>A escolha entre <code>iter()</code>, <code>iter_mut()</code> e <code>into_iter()</code> é fundamental. Use <code>iter()</code> para não modificar e manter a propriedade; <code>iter_mut()</code> para modificar in-place; e <code>into_iter()</code> quando quiser consumir o vetor e obter a propriedade dos elementos. Operações que consomem o vetor como <code>into_iter()</code> são geralmente mais eficientes porque não precisam gerenciar referências.</p>
<h2>Performance, Alocação de Memória e Boas Práticas</h2>
<p>Vec crescer dinamicamente tem um custo: quando a capacidade é excedida, ele realoca a memória — copiando todos os elementos para um novo bloco maior na heap. Essa é uma operação O(n) que deve ser evitada ao máximo. Se você sabe que precisará armazenar 10.000 elementos, aloque essa capacidade desde o início com <code>Vec::with_capacity(10_000)</code>.</p>
<pre><code class="language-rust">fn main() {
// Ineficiente: múltiplas realocações
let mut lento = Vec::new();
for i in 0..100_000 {
lento.push(i);
}
// Eficiente: uma alocação única
let mut rapido = Vec::with_capacity(100_000);
for i in 0..100_000 {
rapido.push(i);
}
// Reserve espaço adicional se necessário
let mut reservado = vec![1, 2, 3];
reservado.reserve(1000);
// Métodos úteis
println!("Está vazio? {}", reservado.is_empty());
reservado.clear(); // Remove todos sem deallocar
println!("Após clear: len={}, capacity={}",
reservado.len(),
reservado.capacity());
}</code></pre>
<p>Métodos como <code>reserve()</code> pré-alocam espaço sem adicionar elementos; <code>clear()</code> remove todos os itens mas mantém a capacidade; e <code>shrink_to_fit()</code> reduce a capacidade ao comprimento atual, útil quando você sabe que não adicionará mais elementos. Use slices (<code>&[T]</code>) em assinaturas de funções em vez de <code>&Vec<T></code> — slices são mais flexíveis e aceitam tanto referências para vetores quanto para arrays primitivos.</p>
<h2>Conclusão</h2>
<p>Vec<T> é a espinha dorsal de estruturas de dados complexas em Rust. Os três conceitos essenciais que você dominou aqui são: (1) a distinção entre capacidade e comprimento, que determina a eficiência de suas operações; (2) o sistema de propriedade e empréstimo, que garante segurança de memória sem garbage collector; (3) a importância de pré-alocar capacidade quando o tamanho final é conhecido. Domine essas lições e você terá ferramentas para escrever código Rust rápido e seguro.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://doc.rust-lang.org/std/vec/struct.Vec.html" target="_blank" rel="noopener noreferrer">The Rust Standard Library: Vec<T></a></li>
<li><a href="https://doc.rust-lang.org/book/ch08-01-vectors.html" target="_blank" rel="noopener noreferrer">The Rust Programming Language - Chapter 8: Common Collections</a></li>
<li><a href="https://doc.rust-lang.org/rust-by-example/std/vec.html" target="_blank" rel="noopener noreferrer">Rust By Example: Vectors</a></li>
<li><a href="https://doc.rust-lang.org/nomicon/layout.html" target="_blank" rel="noopener noreferrer">The Rustonomicon: Memory Layout</a></li>
<li><a href="https://www.oreilly.com/library/view/programming-rust-2nd/9781492052586/" target="_blank" rel="noopener noreferrer">Programming Rust: Fast Systems Programming - Jim Blandy & Jason Orendorff (O'Reilly Media)</a></li>
</ul>