Comentários e documentação
Nesta aula, você aprenderá a usar comentários de linha e bloco em Rust, escrever documentação com doc comments (///) e gerar documentação HTML com cargo doc. Também verá como criar exemplos testáveis dentro da documentação.
Comentários e documentação são partes essenciais de qualquer código-fonte. Em Rust, você pode adicionar comentários para explicar o funcionamento interno do código, além de gerar documentação automática a partir de doc comments. Esta aula cobre os tipos de comentários, a sintaxe de documentação e como usar a ferramenta cargo doc para produzir documentação HTML. Também exploraremos exemplos testáveis, que garantem que a documentação permaneça atualizada e funcional.
Comentários de linha e bloco
Em Rust, comentários de linha são iniciados por // e se estendem até o final da linha. Eles são usados para explicar trechos específicos de código, temporariamente desabilitar código ou adicionar notas. Já os comentários de bloco são delimitados por /* e */ e podem abranger várias linhas. Embora menos comuns, são úteis para comentar grandes blocos de código.
Exemplo de comentários de linha e bloco:
// Isto é um comentário de linha
/*
Isto é um comentário de bloco
que pode ocupar várias linhas
*/
fn main() {
// Comentário de linha explicando a próxima linha
let x = 5; // Comentário no final da linha
/* Comentário de bloco dentro de uma função */
println!("x é {}", x);
}É importante notar que comentários de bloco podem ser aninhados? Não, em Rust comentários de bloco não podem ser aninhados. Se você tentar /* /* */ */, o primeiro */ encerra o comentário, causando um erro de sintaxe. Para comentar blocos que já contêm comentários, prefira usar // em cada linha.
Doc comments (///)
Doc comments são um tipo especial de comentário que geram documentação externa. Eles são escritos com três barras /// e podem ser colocados antes de itens como funções, structs, enums, módulos, etc. O conteúdo é interpretado como Markdown e pode incluir seções, exemplos, links e muito mais. Além disso, doc comments podem ser usados com //! para documentar o item que os contém (como um módulo ou crate).
Exemplo de doc comment para uma função:
/// Calcula a soma de dois números.
///
/// # Exemplo
///
/// ```
/// let resultado = soma(2, 3);
/// assert_eq!(resultado, 5);
/// ```
pub fn soma(a: i32, b: i32) -> i32 {
a + b
}Doc comments suportam tags comuns do Markdown, como # Exemplo, # Panics, # Errors, # Safety. Eles também podem conter links para outros itens da documentação usando colchetes: [`soma`].
cargo doc
O comando cargo doc gera a documentação HTML a partir dos doc comments do seu código. Ele usa o rustdoc internamente e produz uma página web para cada crate e seus itens. Para gerar a documentação, execute cargo doc no diretório do seu projeto. A documentação será salva em target/doc. Você pode abrir o arquivo target/doc/<nome_do_crate>/index.html no navegador.
Para visualizar a documentação diretamente, use cargo doc --open, que gera e abre a página no navegador. Além disso, você pode documentar seu crate com doc comments no arquivo lib.rs ou main.rs usando //!:
//! # Meu Crate
//!
//! Uma biblioteca para cálculos matemáticos.
/// Soma dois números.
pub fn soma(a: i32, b: i32) -> i32 {
a + b
}O cargo doc também gera documentação para dependências, a menos que você use a flag --no-deps. Para personalizar a documentação, você pode adicionar atributos como #![doc(html_logo_url = "...")] no crate root.
Exemplos testáveis
Uma das grandes vantagens dos doc comments em Rust é que você pode incluir exemplos de código que são executados como testes. Isso garante que os exemplos na documentação estejam sempre corretos. Para criar um exemplo testável, use a sintaxe de bloco de código com ``` e, opcionalmente, especifique ignore, no_run, compile_fail, etc., para controlar o comportamento.
Exemplo de um doc comment com um exemplo testável:
/// Calcula o fatorial de um número.
///
/// # Exemplo
///
/// ```
/// use meu_crate::fatorial;
///
/// assert_eq!(fatorial(5), 120);
/// ```
pub fn fatorial(n: u32) -> u32 {
(1..=n).product()
}Para executar os exemplos como testes, use cargo test. O rustdoc compila e executa cada bloco de código marcado como ``` (a menos que seja ignore). Se o exemplo falhar, o teste falha, mantendo a documentação sincronizada com o código.
Você também pode usar atributos como ```no_run para exemplos que não devem ser executados (ex.: código que faz I/O), ```compile_fail para exemplos que devem falhar na compilação, e ```edition2018 para especificar a edição do Rust.
Boas práticas
- Sempre documente funções públicas com doc comments, explicando o que fazem, parâmetros, retorno e possíveis panics.
- Use exemplos testáveis sempre que possível para garantir que a documentação não fique desatualizada.
- Para módulos e crates, use //! para fornecer uma visão geral.
- Mantenha os comentários de linha concisos e evite comentários óbvios que apenas repetem o código.
Referências
- Rust by Example - Comments
- The Rust Programming Language - Comments
- Rustdoc documentation
- cargo doc command
- Documentation tests
Exercícios
Escreva um comentário de linha e um comentário de bloco em uma função
mainque imprime "Olá, mundo!". Use os comentários para explicar cada parte.✓ Resposta:fn main() { // Isto é um comentário de linha println!("Olá, mundo!"); // Imprime a mensagem /* Isto é um comentário de bloco que pode ter várias linhas */ }Crie uma função pública
multiplicaque recebe dois inteirosi32e retorna o produto. Adicione um doc comment com um exemplo testável.✓ Resposta:/// Multiplica dois números. /// /// # Exemplo /// /// ``` /// use meu_crate::multiplica; /// /// assert_eq!(multiplica(4, 5), 20); /// ``` pub fn multiplica(a: i32, b: i32) -> i32 { a * b }Use
cargo docpara gerar a documentação de um crate simples que contém a função do exercício anterior. Explique o comando usado.✓ Resposta:O comando é
cargo doc --open. Ele gera a documentação HTML e a abre no navegador. A documentação será salva emtarget/doc/<nome_do_crate>/index.html.Escreva um doc comment para um módulo usando
//!que descreve o propósito do módulo e inclui um exemplo de uso.✓ Resposta://! # Módulo de operações matemáticas //! //! Este módulo fornece funções básicas como soma e multiplicação. //! //! # Exemplo //! //! ``` //! use meu_crate::operacoes; //! //! let s = operacoes::soma(2, 3); //! assert_eq!(s, 5); //! ``` pub fn soma(a: i32, b: i32) -> i32 { a + b } pub fn multiplica(a: i32, b: i32) -> i32 { a * b }No doc comment da função do exercício 2, modifique o exemplo para usar
no_rune explique por que isso seria útil.✓ Resposta:/// Multiplica dois números. /// /// # Exemplo /// /// ```no_run /// use meu_crate::multiplica; /// /// let resultado = multiplica(4, 5); /// println!("Resultado: {}", resultado); /// ``` pub fn multiplica(a: i32, b: i32) -> i32 { a * b }O atributo
no_runimpede que o exemplo seja executado durantecargo test, mas ainda assim é compilado. Isso é útil quando o exemplo realiza operações com efeitos colaterais, como I/O, ou quando a execução não é necessária para verificar a correção.