输出宏
Rust 的打印(输出)功能由 std::fmt 模块中的一系列宏实现,常用宏说明如下:
format!:将格式化文本写入字符串print!:输出内容到控制台(标准输出)println!:同print!,末尾自动换行eprint!:输出内容到标准错误流eprintln!:同eprint!,末尾自动换行
凡是有ln结尾的,就是增加了换行符,输出完毕后会换行。
e开头的e,表示error,用来输出错误信息
以上宏的格式化语法完全一致,且 Rust 会在编译阶段校验格式化代码是否合法。
使用例子
基础占位符 {}
{} 是通用占位符,会按顺序替换为后续传入参数,并自动转为字符串输出。
fn main() {
println!("{} days", 31);
// 输出:31 days
}Code language: JavaScript (javascript)
位置参数
在 {} 内填写数字索引(从 0 开始),可手动指定使用第几个参数,支持参数复用、打乱顺序。
fn main() {
println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");
// 输出:Alice, this is Bob. Bob, this is Alice
}Code language: JavaScript (javascript)
上面例子,可以看到参数的索引可以不从0 1 2 …排序下去的,可以打乱。后面的参数”Alice”, “Bob” ,Alice就是0, Bob就是1 。这样排序下去。
命名参数
如果你觉得上面的通过索引来应用不够直观,可以使用“命名参数”,格式字符串内使用 {参数名},调用时以 参数名=值 形式传参,顺序不受限制,可读性更强。
fn main() {
println!("{subject} {verb} {object}",
object="the lazy dog",
subject="the quick brown fox",
verb="jumps over");
// 输出:the quick brown fox jumps over the lazy dog
}Code language: JavaScript (javascript)
相当于,给后面的参数一个名称,然后签名的格式化字符串,你可以用{参数名},来表示,更加直观。
进制格式化(:格式符)
在占位符内通过 : 加格式字符,可将数字转为二进制、八进制、十六进制等不同进制。
:b:二进制:o:八进制:x:小写十六进制
fn main() {
println!("十进制: {}", 69420); // 69420
println!("二进制: {:b}", 69420); // 10000111100101100
println!("八进制: {:o}", 69420); // 207454
println!("十六进制:{:x}", 69420); // 10f2c
}Code language: JavaScript (javascript)
宽度对齐与补位
1 右对齐(>宽度)
{:>n} 表示总宽度为 n,内容右对齐,左侧补空格。
fn main() {
println!("{number:>5}", number=1);
// 总宽度5,左侧补4个空格 → 输出: 1
}Code language: JavaScript (javascript)

2 补零对齐
在对齐符号前加 0,使用数字 0 替代空格补位。
:0>5:右对齐,左侧补 0:0<5:左对齐,右侧补 0
fn main() {
println!("{number:0>5}", number=1); // 右对齐补0 → 00001
println!("{number:0<5}", number=1); // 左对齐补0 → 10000
}Code language: JavaScript (javascript)
还可以用其他任何的字符的,不一定是0,例如下面例子,签名补大写字母A
fn main() {
println!("{number:A>5}", number=1); // 右对齐补0 → 00001
println!("{number:A<5}", number=1); // 左对齐补0 → 10000
}Code language: JavaScript (javascript)

3 动态宽度(变量名$)
宽度不再写死,通过 变量名$ 引用外部命名参数 / 变量,实现动态控制宽度。
也就是宽度,可以通过变量,来控制,而不是代码固定写死。
fn main() {
// 方式1:配合命名参数
println!("{number:0>width$}", number=1, width=8);
// 方式2:直接引用代码内变量(Rust 1.58+ 支持)
let number: f64 = 1.0;
let width: usize = 8;
println!("{number:>width$}"); // 输出: 1
}Code language: JavaScript (javascript)

编译期参数校验
Rust 会在编译阶段检查占位符数量和传入参数数量是否匹配,参数缺失直接编译报错。
fn main() {
// 2个占位符,但只传1个参数,编译失败
println!("My name is {0}, {1} {0}", "Bond");
// 修正:补充参数 "James"
println!("My name is {0}, {1} {0}", "Bond", "James");
}Code language: JavaScript (javascript)

编译提示,{1}位置,无效,因为后面只有一个参数。
错误:引用了不存在的位置参数 1(当前仅传入 1 个参数)
--> D:\rustdemo\hello.rs:3:29
|
3 | println!("My name is {0}, {1} {0}", "Bond");
| ^
|
= 提示:位置参数从 0 开始编号
错误:编译终止,共 1 个错误Code language: JavaScript (javascript)
自定义类型格式化限制
默认情况下,{} 只能格式化实现了 fmt::Display 特征的类型。 自定义结构体默认未实现该特征,直接使用 {} 打印会编译报错。
fn main() {
struct Structure(i32);
// 下方代码无法编译
println!("{}", Structure(3));
}Code language: JavaScript (javascript)

错误[E0277]:结构体 `Structure` 未实现 `std::fmt::Display` 特征
--> D:\rustdemo\hello.rs:4:20
4 | println!("{}", Structure(3));
| -- ^^^^^^^^^^^^ 该类型无法使用默认格式器输出
| |
| 此处格式参数要求类型实现 Display 特征
提示:`Structure` 结构体没有实现 `std::fmt::Display` 特征
--> D:\rustdemo\hello.rs:2:2
2 | struct Structure(i32);
| ^^^^^^^^^^^^^^^^
补充说明:格式字符串中,可以尝试改用 `{:?}`(或 `{:#?}` 美化打印)
编译终止,共 1 处错误。
如需查看该错误详情,可执行命令:rustc --explain E0277Code language: JavaScript (javascript)
* 1 如果您需要输出结构体,则需要实现Display特征(暂时理解就可以,后面会学习)
use std::fmt;
struct Structure(i32);
// 为结构体实现 Display 特征
impl fmt::Display for Structure {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// self.0 访问元组结构体内部的 i32 值
write!(f, "数值:{}", self.0)
}
}
fn main() {
println!("{}", Structure(3));
}Code language: PHP (php)
* 2 临时调试 → 使用调试格式 {:?} / {:#?}
适合程序员调试用,如果你不是正式环境,只是为了调试这个结构体里面的值是什么,你可以使用调试特性Debug
Rust 为自定义类型默认实现了调试特征 Debug,用 {:?} 即可打印:
#[derive(Debug)]
#[allow(dead_code)] // 屏蔽未使用代码/字段警告
struct Structure(i32);
fn main() {
println!("{:?}", Structure(3));
println!("{:#?}", Structure(3));
}Code language: PHP (php)
* std::fmt 两大核心格式化特征
std::fmt 模块包含多个控制文本展示的特征,常用两个:
- fmt::Debug 搭配占位符
{:?},专门用于调试场景输出内容。 - fmt::Display 搭配占位符
{},以更规范、友好的形式展示内容,面向普通用户。
标准库内置类型已默认实现这两个特征,可直接打印;自定义类型无法直接使用,需要手动实现对应特征。
为类型实现 fmt::Display 后,会自动附带实现 ToString 特征,支持将该类型转为字符串。
#[allow(dead_code)]
#[allow(dead_code)] 是代码属性,作用于紧随其后的代码项,用来屏蔽 “代码未使用” 的警告。
上面的例子
fn main() {
struct Structure(i32);
// 下方代码无法编译
//println!("{}", Structure(3));
}Code language: JavaScript (javascript)
由于第二句代码println!(“{}”, Structure(3)); 会报错,注释了,如果这个时候执行,
warning: struct `Structure` is never constructed
--> D:\rustdemo\hello.rs:2:12
|
2 | struct Structure(i32);
| ^^^^^^^^^
|
= note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default
warning: 1 warning emitted
Code language: JavaScript (javascript)

会有这样的警告,因为这句代码,struct Structure(i32); 从来没使用。如果你想屏蔽这个警告,可以增加这个标注
fn main() {
#[allow(dead_code)]
struct Structure(i32);
// 下方代码无法编译
//println!("{}", Structure(3));
}Code language: PHP (php)
对于浮点数,保留小数
定义变量 pi = 3.141592,编写格式化输出,保留三位小数,打印内容:Pi is roughly 3.142。
fn main() {
let pi = 3.141592;
println!("Pi is roughly {:.3}", pi);//3.142
println!("Pi is roughly {0}", pi); //3.141592
}Code language: JavaScript (javascript)