Impressão Formatada

A impressão é manipulada por uma série de macros definidas na std::fmt, algumas das quais incluem:

  • format!: escreve o texto formatado para a String.
  • print!: o mesmo que format! mas o texto é imprimido para a consola (io::stdout).
  • println!: o mesmo que print! mas uma nova linha é anexada.
  • eprint!: o mesmo que print! mas o texto é imprimido para o erro padrão (io::stderr).
  • eprintln!: o mesmo que eprint! mas uma nova linha é anexada.

Todos analisam o texto da mesma maneira. Como uma vantagem, a Rust verifica a exatidão da formatação em tempo de compilação:

fn main() {
// Em geral, as `{}` serão automaticamente substituídas por quaisquer
// argumentos. Estes serão convertidos em sequências de caracteres.
println!("{} days", 31);
// Os argumentos posicionais podem ser usados. Especificar um inteiro
// dentro de `{}` determina qual argumento adicional será substituído.
// Os argumentos começam em 0 imediatamente depois da
// sequência de caracteres de formatação.
println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");
// As can named arguments.
println!("{subject} {verb} {object}",
object="the lazy dog",
subject="the quick brown fox",
verb="jumps over");
// Uma formatação diferente pode ser invocada com a especificação do
// carácter de formato depois dum `:`.
println!("Base 10: {}", 69420); // 69420
println!("Base 2 (binary): {:b}", 69420); // 10000111100101100
println!("Base 8 (octal): {:o}", 69420); // 207454
println!("Base 16 (hexadecimal): {:x}", 69420); // 10f2c
println!("Base 16 (hexadecimal): {:X}", 69420); // 10F2C
// Podemos justificar o texto à direita com uma largura especificada.
// Isto resultará em " 1".
// (Quatro espaços em branco e um "1", para uma largura total de 5).
println!("{number:>5}", number=1);
// Podemos acolchoar números com zeros adicionais,
println!("{number:0>5}", number=1); // 00001
// e ajustar à esquerda com a virada do sinal. Isto resultará em "10000".
println!("{number:0<5}", number=1); // 10000
// Podemos usar argumentos nomeados no
// especificador de formato anexando um `$`.
println!("{number:0>width$}", number=1, width=5);
// A Rust ainda verifica para certificar-se
// que o número correto de argumentos são usados.
println!("My name is {0}, {1} {0}", "Bond");
// FIXME ^ Add the missing argument: "James"
// Apenas tipos que implementam `fmt::Display` podem ser formatados com `{}`.
// Os tipos definidos pelo utilizador
// não implementam `fmt::Display` por padrão.
#[allow(dead_code)] // desativa `dead_code` que alerta sobre módulo não usado.
struct Structure(i32);
// Isto não compilará porque `Structure` não implementa `fmt::Display`
// println!("This struct `{}` won't print...", Structure(3));
// TODO ^ Try uncommenting this line
// Para a Rust 1.58 e acima, podemos capturar diretamente o argumento duma
// variável envolvente. Tal como acima, isto resultará em " 1",
// 4 espaços em branco e um "1".
let number: f64 = 1.0;
let width: usize = 5;
println!("{number:>width$}");
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

O std::fmt contém muitas traits que governam a exibição do texto. A forma de base de dois importantes são listados abaixo:

  • fmt::Debug: Usa o marcador {:?}. Formata o texto para fins de depuração.
  • fmt::Display: Usa o marcador {}. Formata o texto duma maneira mais elegante e agradável para o utilizador.

Cá, usamos fmt::Display porque a biblioteca std fornece implementações para estes tipos. Para imprimir texto para tipos personalizados, mais passos são necessários.

Implementar a característica fmt::Display implementa automaticamente a característica ToString que permite-nos converter o tipo para String.

Na linha 46, #[allow(dead_code)] é um atributo que apenas aplica-se ao módulo depois deste.

Atividades

  • Corrija o problema no código acima (vê a FIXME) para que esta execute sem erro.
  • Tente desfazer o comentário da linha que tenta formatar a estrutura Structure (vê TODO)
  • Adicione uma chamada de macro println! que imprime: Pi is roughly 3.142 controlando o número de casas decimais exibido. Para os fins deste exercício, use let pi = 3.141592 como uma estimativa para o pi. (Dica: podemos precisar de consultar a documentação de std::fmt para definir o número de decimais à exibir).

Consulte também:

std::fmt, macros, struct, traits, e dead_code.