Tipos Imprimíveis na Biblioteca Padrão do Rust

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Neste laboratório, explica-se que, para usar os traits de formatação std::fmt, os tipos devem ter uma implementação para serem imprimíveis, o que pode ser fornecido automaticamente para tipos na biblioteca std. Para outros tipos, o trait fmt::Debug pode ser derivado para habilitar a impressão. O trait fmt::Debug torna simples a implementação de tipos imprimíveis, enquanto fmt::Display precisa ser implementado manualmente. O trait fmt::Debug permite que todos os tipos derivem a implementação para impressão, e o mesmo se aplica a {:?} para tipos da biblioteca std. O laboratório também menciona o uso de {:?} para impressão e fornece um exemplo de como usá-lo para imprimir diferentes tipos. Adicionalmente, o conceito de "pretty printing" (formatação elegante) com {:#?} é introduzido, o que fornece uma representação mais elegante de estruturas de dados. Finalmente, é mencionado que fmt::Display pode ser implementado manualmente para ter controle sobre a exibição dos tipos.

Nota: Se o laboratório não especificar um nome de arquivo, você pode usar qualquer nome de arquivo que desejar. Por exemplo, você pode usar main.rs, compilar e executá-lo com rustc main.rs && ./main.

Debug (Depuração)

Todos os tipos que desejam usar os traits de formatação std::fmt requerem uma implementação para serem imprimíveis. Implementações automáticas são fornecidas apenas para tipos como os da biblioteca std. Todos os outros devem ser implementados manualmente de alguma forma.

O trait fmt::Debug torna isso muito simples. Todos os tipos podem derive (criar automaticamente) a implementação fmt::Debug. Isso não é verdade para fmt::Display, que deve ser implementado manualmente.

// Esta estrutura não pode ser impressa nem com `fmt::Display` nem
// com `fmt::Debug`.
struct UnPrintable(i32);

// O atributo `derive` cria automaticamente a implementação
// necessária para tornar esta `struct` imprimível com `fmt::Debug`.
#[derive(Debug)]
struct DebugPrintable(i32);

Todos os tipos da biblioteca std são automaticamente imprimíveis com {:?} também:

// Deriva a implementação `fmt::Debug` para `Structure`. `Structure`
// é uma estrutura que contém um único `i32`.
#[derive(Debug)]
struct Structure(i32);

// Coloca uma `Structure` dentro da estrutura `Deep`. Torna-a imprimível
// também.
#[derive(Debug)]
struct Deep(Structure);

fn main() {
    // Imprimir com `{:?}` é semelhante a com `{}`.
    println!("{:?} meses em um ano.", 12);
    println!("{1:?} {0:?} é o nome do {actor:?}.",
             "Slater",
             "Christian",
             actor="ator's");

    // `Structure` é imprimível!
    println!("Agora {:?} irá imprimir!", Structure(3));

    // O problema com `derive` é que não há controle sobre como
    // os resultados aparecem. E se eu quiser que isso mostre apenas um `7`?
    println!("Agora {:?} irá imprimir!", Deep(Structure(7)));
}

Portanto, fmt::Debug definitivamente torna isso imprimível, mas sacrifica um pouco de elegância. Rust também fornece "pretty printing" (formatação elegante) com {:#?}.

#[derive(Debug)]
struct Person<'a> {
    name: &'a str,
    age: u8
}

fn main() {
    let name = "Peter";
    let age = 27;
    let peter = Person { name, age };

    // Pretty print (Formatação elegante)
    println!("{:#?}", peter);
}

Pode-se implementar manualmente fmt::Display para controlar a exibição.

Resumo

Parabéns! Você concluiu o laboratório de Debug. Você pode praticar mais laboratórios no LabEx para aprimorar suas habilidades.