Code review em Rust: o que verificar e como dar feedback

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução

Code review é uma parte essencial do desenvolvimento profissional. No ecossistema Rust, onde a segurança de memória e o desempenho são prioridades, a revisão de código adquire uma importância especial. O uso incorreto de unsafe, a ignorância das regras de ownership ou panics implícitos podem anular todas as vantagens da linguagem.

Neste artigo, vamos analisar o que observar durante um code review em Rust, como estruturar o feedback e quais ferramentas podem ajudar a automatizar as verificações. O material será útil tanto para iniciantes quanto para desenvolvedores experientes que desejam organizar o processo de revisão.



1. Segurança: verificação de código unsafe e panics implícitos

Rust garante segurança de memória, mas unsafe é uma renúncia a essas garantias. Cada bloco unsafe deve ser cuidadosamente verificado.



O que verificar em código unsafe?

  • Correção dos ponteiros: se há desreferenciamento de ponteiro nulo ou dangling pointer.
  • Alinhamento de dados: se o alinhamento está correto ao fazer cast de raw pointers.
  • Aliasing: se há violações das regras de aliasing (por exemplo, borrow mutável e imutável simultâneo).
  • Invariantes: se os invariantes das estruturas de dados são mantidos (por exemplo, um heap binário continua sendo um heap).


// Exemplo ruim: cast inseguro sem verificação de alinhamentofn bad_unsafe(data: &[u8]) -> &[u32] {    unsafe {        std::slice::from_raw_parts(            data.as_ptr() as *const u32,            data.len() / 4        )    }}

// Exemplo bom: com verificação de alinhamentofn good_unsafe(data: &[u8]) -> Option<&[u32]> { if data.len() % 4 != 0 || data.as_ptr() as usize % 4 != 0 { return None; } Some(unsafe { std::slice::from_raw_parts( data.as_ptr() as *const u32, data.len() / 4 ) })}


Panics implícitos

Em Rust, muitas operações podem causar panic: unwrap(), expect(), panic!(), divisão por zero, acesso fora dos limites de um array. No code review, deve-se prestar atenção a:

  • Use unwrap() apenas em testes ou quando o erro é realmente impossível.
  • Prefira unwrap_or(), unwrap_or_else() ou tratamento via match.
  • Verifique se todas as conversões com as não perdem dados (por exemplo, u64 as u32).


// Ruim: panic implícitolet value = some_option.unwrap();

// Bom: tratamento explícitolet value = some_option.unwrap_or_else(|| { log::error!("Missing expected value"); default_value()});


2. Ownership e borrowing: erros típicos

O sistema de ownership é a principal característica do Rust. Os erros do compilador aqui são os melhores amigos, mas o code review ajuda a encontrar erros lógicos que o compilador não detecta.



Clonagens desnecessárias

Um problema comum é clonar onde se poderia passar uma referência. Isso reduz o desempenho e aumenta o uso de memória.



// Ruim: clonagem de toda a stringfn process(data: Vec<String>) {    for item in data {        let cloned = item.clone();        do_something(&cloned);    }}

// Bom: passagem de referênciafn process(data: &[String]) { for item in data { do_something(item); }}


Borrows e lifetimes desnecessários

Verifique se o tempo de vida das referências não é muito longo. Às vezes, é possível simplificar a assinatura da função removendo anotações de lifetime extras.



// Complexo: lifetimes desnecessáriosfn longest<'a>(x: &'a str, y: &'a str) -> &'a str {    if x.len() > y.len() { x } else { y }}

// Se

Blogs

Book Recommendations