Rust: uma linguagem que faz você pensar de forma diferente
\n\nVocê decidiu conquistar o Rust. Ótimo. Esta não é apenas mais uma linguagem — é um desafio. O Rust quebra os padrões que estamos acostumados a ver em Python, JavaScript ou até mesmo C++. Ele faz você pensar sobre memória, segurança e concorrência em um novo nível.
\n\nUma entrevista de Rust não é um exame de sintaxe. É uma verificação de como você pensa. Os entrevistadores querem ver se você entende a filosofia da linguagem: ownership, borrowing, lifetimes. Neste artigo, vamos analisar tópicos e perguntas reais que serão feitos a você e mostrar exemplos de código que ajudarão a passar na entrevista.
\n\nPronto? Vamos lá.
\n\n1. Ownership — o fundamento sem o qual você não vai a lugar nenhum
\n\nO primeiro e mais importante bloco. Se você não entende ownership, você não entende Rust. Na entrevista, certamente pedirão que você explique como funciona a transferência de ownership e escreva um código que demonstre isso.
\n\nRegras-chave de ownership:
\n- \n
- Cada valor em Rust tem exatamente um dono. \n
- Quando o dono sai do escopo, o valor é removido. \n
- O ownership pode ser transferido (move) ou emprestado temporariamente (borrow). \n
Exemplo: o que este código imprime?
\nfn main() {\n let s1 = String::from("hello");\n let s2 = s1;\n println!("{}", s1); // Erro!\n}\n\nResposta correta: erro de compilação. s1 foi movido para s2, e s1 não é mais válido. O entrevistador quer ouvir que você entende move semantics e por que o Rust é tão rigoroso quanto a isso.
2. Borrowing e Referências (Borrowing & References)
\n\nDepois de ownership — borrowing. Como pegar uma referência sem tirar o ownership? E o principal — como não violar as regras do compilador.
\n\nRegras de borrowing:
\n- \n
- Pode haver quantas referências imutáveis (&T) forem necessárias. \n
- Pode haver apenas uma referência mutável (&mut T). \n
- Não é possível ter &T e &mut T simultaneamente para o mesmo valor. \n
Exemplo: encontre o erro
\nfn main() {\n let mut s = String::from("hello");\n let r1 = &s;\n let r2 = &mut s;\n println!("{} {}", r1, r2);\n}\n\nErro: criamos uma referência imutável r1 e depois uma mutável r2. O compilador não permitirá. Explicação: isso é uma proteção contra data races em tempo de compilação.
3. Lifetimes — o tópico que assusta todo mundo
\n\nLifetimes não são mágica. São anotações que ajudam o compilador a entender por quanto tempo as referências permanecem válidas. Na entrevista, pedirão que você explique para que servem e escreva uma função com parâmetros de lifetime explícitos.
\n\nPergunta típica:
\nEscreva uma função que retorna a string mais longa entre duas. Como você especificaria os lifetimes?
\n\nfn longest<'a>(x: &'a str, y: &'a str) -> &'a str {\n if x.len() > y.len() { x } else { y }\n}\n\nAqui, 'a é o lifetime comum que garante que a referência retornada será válida enquanto ambas as referências de entrada forem válidas. O entrevistador apreciará se você mencionar lifetime elision — quando o Rust infere os lifetimes automaticamente para casos simples.
4. Enums e Pattern Matching — o poder do Rust
\n\nRust não tem null. Em vez disso, temos Option<T> e Result<T, E>. Na entrevista, pedirão que você escreva tratamento de erros usando match.
Exemplo: divisão segura
\nfn safe_divide(a: f64, b: f64) -> Option<f64> {\n if b == 0.0 { None } else { Some(a / b) }\n}\n\nfn main() {\n match safe_divide(10.0, 0.0) {\n Some(result) => println!("Result: {}", result),\n None => println!("Cannot divide by zero"),\n }\n}\n\nMostre