Por que Rust quebra padrões (e isso é normal)
\n\nRust é uma linguagem-desafio. Ela não perdoa preguiça, não dá folga para "está bom assim" e exige do programador um profundo entendimento de memória. É por isso que muitos desenvolvedores, especialmente depois de Python ou JavaScript, sofrem um choque cultural. Você está acostumado que o interpretador limpa a bagunça sozinho? Esqueça. Rust diz: "Você é o dono da sua memória, mas por cada erro pagará com a compilação".
\n\nNeste artigo, analisaremos 10 erros principais ao aprender Rust que iniciantes cometem. Não vamos apenas listá-los — mostraremos como corrigi-los com código real. Se você está começando sua jornada em Rust ou já bateu algumas cabeças — este material é para você.
\n\nErro nº1: Ignorar o borrow checker
\n\nA reclamação mais comum: "Por que o compilador reclama de tudo?!". O Borrow checker não é um inimigo, mas seu melhor amigo. Ele não permite que você atire no próprio pé. O problema é que iniciantes tentam contorná-lo, em vez de entender a lógica.
\n\nComo é um erro típico
\n\nfn main() {\n let mut s = String::from("hello");\n let r1 = &s;\n let r2 = &mut s; // ERRO!\n println!("{}, {}", r1, r2);\n}\n\nO compilador exibirá: cannot borrow `s` as mutable because it is also borrowed as immutable. O iniciante entra em pânico, remove o mut ou começa a espalhar clone(). A solução correta é reduzir o escopo dos empréstimos.
Correção
\n\nfn main() {\n let mut s = String::from("hello");\n let r1 = &s;\n println!("{}", r1); // o empréstimo imutável termina aqui\n let r2 = &mut s;\n println!("{}", r2);\n}\n\nDica: Veja o borrow checker como um parceiro ciumento — ele permite apenas um empréstimo mutável ou quantos imutáveis você quiser, mas não ao mesmo tempo.
\n\nErro nº2: Medo de lifetimes (tempos de vida)
\n\nLifetimes assustam os iniciantes mais do que tudo. A sintaxe 'a parece mágica, mas na verdade são apenas anotações para o borrow checker que dizem: "Esta referência vive tanto quanto aquela".
Problema: retornar uma referência de uma função
\n\nfn longest(x: &str, y: &str) -> &str { // ERRO: missing lifetime specifier\n if x.len() > y.len() { x } else { y }\n}\n\nO compilador não sabe qual referência será retornada. A solução é indicar explicitamente que ambas as referências vivem o mesmo tempo:
\n\nfn longest<'a>(x: &'a str, y: &'a str) -> &'a str {\n if x.len() > y.len() { x } else { y }\n}\n\nDica: Em 90% dos casos, os lifetimes podem ser omitidos — o compilador os infere (elision). Se ele pedir, basta adicionar 'a e não entre em pânico.
Erro nº3: Uso excessivo de clone()
\n\nQuando o borrow checker não deixa passar, iniciantes usam .clone(). Isso funciona, mas mata a principal vantagem do Rust — as zero-cost abstractions. O código começa a ficar lento e consumir memória.
Exemplo ruim
\n\nlet s1 = String::from("hello");\nlet s2 = s1.clone(); // por quê?!\nprintln!("{}", s1); // funciona só por causa do clone\n\n\nÉ melhor usar empréstimo ou movimentação:
\n\nlet s1 = String::from("hello");\nlet s2 = &s1; // empréstimo\nprintln!("{}", s1); // tudo ok\n\n\nRegra de ouro: Use clone() apenas para estruturas de dados complexas onde o empréstimo é impossível (por exemplo, ao passar para outra thread).
\n\nErro nº4: Não entender ownership (propriedade)
\n\nRust é a única linguagem onde ownership não é filosofia, mas uma regra de compilação. Cada valor tem exatamente um dono. Quando em