Como passar na entrevista de Rust: principais perguntas
Rust é uma das linguagens de programação mais requisitadas em 2025. Ela combina a performance de C/C++ com segurança de memória, tornando-a a escolha ideal para programação de sistemas, WebAssembly e projetos blockchain. No entanto, a entrevista de Rust frequentemente assusta os candidatos devido ao sistema rigoroso de ownership, borrowing e lifetimes. Neste artigo, vamos analisar as 10 principais perguntas que você certamente enfrentará e mostrar as respostas corretas com exemplos de código.
1. O que é ownership e como funciona?
Ownership é a base do Rust. Cada valor em Rust tem exatamente um dono. Quando o dono sai de escopo, o valor é automaticamente destruído.
fn main() { let s = String::from("hello"); // s é o dono da string let t = s; // a ownership é movida para t // println!("{}", s); // ERRO: s não é mais dono do valor println!("{}", t); // OK}O que perguntam na entrevista: explique a diferença entre move e copy. Tipos que implementam a trait Copy (por exemplo, i32, bool) são copiados, não movidos.
2. Como funciona o borrowing?
Borrowing permite usar um valor temporariamente sem transferir a ownership. Existem dois tipos de borrowing: imutável (&T) e mutável (&mut T).
fn main() { let mut s = String::from("hello"); let r1 = &s; // borrowing imutável let r2 = &s; // pode ter vários imutáveis // let r3 = &mut s; // ERRO: não pode ter mutável e imutável simultaneamente println!("{} {}", r1, r2); let r3 = &mut s; // OK: depois que r1 e r2 saíram de escopo r3.push_str(" world"); println!("{}", r3);}Regra chave: a qualquer momento, pode haver apenas um borrowing mutável ou qualquer número de borrowings imutáveis.
3. O que são lifetimes?
Lifetimes são anotações que o compilador Rust precisa para verificar se as referências não se tornam dangling. Elas são mais usadas em funções que retornam referências.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y }}
fn main() { let s1 = String::from("longa"); let s2 = "curta"; let result = longest(&s1, s2); println!("A string mais longa: {}", result);}Dica: na maioria dos casos, o compilador infere os lifetimes automaticamente (elision). Anotações são necessárias apenas para casos complexos.
4. O que são traits e como usá-las?
Traits são análogas a interfaces em outras linguagens. Elas definem comportamentos comuns para diferentes tipos.
trait Summary { fn summarize(&self) -> String;}
struct Article { title: String, content: String,}
impl Summary for Article { fn summarize(&self) -> String { format!("{}: {}...", self.title, &self.content[..20]) }}
fn main() { let article = Article { title: String::from("Rust"), content: String::from("Rust é uma linguagem segura e rápida"), }; println!("{}", article.summarize());}Importante: traits podem ter implementações padrão e podem ser parametrizadas (traits genéricas).
5. Qual a diferença entre String e &str?
Esta é uma das perguntas mais frequentes. String é uma string mutável e owned, armazenada no heap. &str é um borrowing imutável de um string slice, que pode referenciar uma String, um literal de string ou parte de uma string.
fn main() { let s1 = String::from("hello"); // String let s2: &st