格式化打印
打印操作由 std::fmt
中定义的一系列 宏
处理,其中一些包括:
format!
:将格式化后的文本写入 String
。
print!
:与 format!
相同,但文本会打印到控制台(io::stdout
)。
println!
:与 print!
相同,但会追加一个换行符。
eprint!
:与 print!
相同,但文本会打印到标准错误输出(io::stderr
)。
eprintln!
:与 eprint!
相同,但会追加一个换行符。
所有这些宏都以相同的方式解析文本。另外,Rust 在编译时会检查格式化的正确性。
fn main() {
// 一般来说,`{}` 会自动被任何参数替换。这些参数会被字符串化。
println!("{} 天", 31);
// 可以使用位置参数。在 `{}` 内指定一个整数,决定将替换哪个额外的参数。参数从格式字符串后的 0 开始。
println!("{0}, 这是 {1}。{1}, 这是 {0}", "爱丽丝", "鲍勃");
// 也可以使用命名参数。
println!("{subject} {verb} {object}",
object="那只懒狗",
subject="那只敏捷的棕色狐狸",
verb="跳过");
// 通过在 `:` 后指定格式字符,可以调用不同的格式化方式。
println!("十进制: {}", 69420); // 69420
println!("二进制: {:b}", 69420); // 10000111100101100
println!("八进制: {:o}", 69420); // 207454
println!("十六进制: {:x}", 69420); // 10f2c
println!("十六进制: {:X}", 69420); // 10F2C
// 可以使用指定的宽度对文本进行右对齐。这将输出 " 1"。(四个空格和一个 "1",总宽度为 5。)
println!("{number:>5}", number=1);
// 可以用额外的零填充数字,
println!("{number:0>5}", number=1); // 00001
// 通过翻转符号进行左对齐。这将输出 "10000"。
println!("{number:0<5}", number=1); // 10000
// 可以通过在格式说明符后追加 `$` 来在格式说明符中使用命名参数。
println!("{number:0>width$}", number=1, width=5);
// Rust 甚至会检查以确保使用了正确数量的参数。
println!("我的名字是 {0}, {1} {0}", "邦德");
// FIXME ^ 添加缺失的参数:"詹姆斯"
// 只有实现了 `fmt::Display` 的类型才能用 `{}` 进行格式化。用户定义的类型默认不实现 `fmt::Display`。
#[allow(dead_code)] // 禁用 `dead_code`,它会警告未使用的模块
struct Structure(i32);
// 这将无法编译,因为 `Structure` 没有实现 `fmt::Display`。
// println!("这个结构体 `{}` 不会打印...", Structure(3));
// TODO ^ 尝试取消注释这一行
// 对于 Rust 1.58 及以上版本,可以直接从周围的变量捕获参数。就像上面一样,这将输出
// " 1",四个空格和一个 "1"。
let number: f64 = 1.0;
let width: usize = 5;
println!("{number:>width$}");
}
std::fmt
包含许多用于控制文本显示的 特性
。下面列出了两个重要特性的基本形式:
fmt::Debug
:使用 {:?}
标记。用于格式化文本以进行调试。
fmt::Display
:使用 {}
标记。以更优雅、用户友好的方式格式化文本。
在这里,我们使用了 fmt::Display
,因为标准库为这些类型提供了实现。要打印自定义类型的文本,还需要更多步骤。
实现 fmt::Display
特性会自动实现 ToString
特性,这使我们能够将类型转换为 String
。
在第 43 行,#[allow(dead_code)]
是一个 [属性]
,仅应用于它后面的模块。
活动
- 修复上述代码中的问题(见 FIXME),使其能够无错误运行。
- 尝试取消注释尝试格式化
Structure
结构体的那一行(见 TODO)
- 添加一个
println!
宏调用,通过控制显示的小数位数来打印:Pi 约为 3.142
。在本练习中,使用 let pi = 3.141592
作为 pi 的近似值。(提示:你可能需要查看 std::fmt
文档以设置要显示的小数位数)