在 Rust 开发中,格式化输出是调试、日志打印、字符串构造的核心技能。Rust 提供了一套强大且灵活的输出宏体系,支持普通打印、调试输出、自定义格式、精度控制、对齐填充等几乎所有场景。
本文结合完整知识点,为你总结 Rust 中所有输出方式 + 格式化语法,通俗易懂、全是干货,看完就能直接用在项目里。
一、Rust 五大输出宏(必背)
Rust 提供 5 个核心输出宏,分工明确:
| 宏 | 作用 | 输出目标 | 换行 |
|---|---|---|---|
print! |
格式化输出文本 | 标准输出 (stdout) | ❌ |
println! |
格式化输出文本 + 自动换行 | 标准输出 | ✅ |
format! |
生成格式化字符串(不打印,返回 String) | 内存字符串 | --- |
eprint! |
错误信息输出 | 标准错误 (stderr) | ❌ |
eprintln! |
错误信息输出 + 自动换行 | 标准错误 | ✅ |
简单示例
rust
fn main() {
// 打印不换行
print!("Hello ");
// 打印并换行
println!("World!");
// 生成格式化字符串(最常用!)
let s = format!("{} + {}", 1, 2);
println!("{s}");
// 错误输出(用于日志、报错)
eprintln!("错误:文件打开失败");
}
二、两种核心占位符:{} 与 {:?}
Rust 抛弃了 C 语言的 %d/%s,只用两种占位符搞定一切:
1. {} ------ 面向用户的友好输出
- 实现
std::fmt::Display特征 - 用于最终用户展示
- 字符串、数字默认支持
- 结构体不能直接用 ,需手动实现
Display
rust
println!("{}", 123);
println!("{}", "hello");
2. {:?} ------ 面向调试的输出
- 实现
std::fmt::Debug特征 - 用于开发调试
- 绝大多数类型可直接用(数组、Vec、枚举等)
- 结构体只需
#[derive(Debug)]
rust
#[derive(Debug)]
struct User { name: String }
println!("{:?}", User { name: "Zhang".into() });
3. {:#?} ------ 美化调试输出(自动换行 + 缩进)
rust
println!("{:#?}", vec![1,2,3]);
输出结构清晰,适合复杂数据调试。
三、自定义类型如何输出?(高频面试 / 开发)
1. 调试用:给结构体加 #[derive(Debug)]
最简单,90% 场景够用。
2. 展示用:手动实现 Display 特征
rust
use std::fmt;
struct Person { name: String, age: u8 }
impl fmt::Display for Person {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "姓名:{},年龄:{}", self.name, self.age)
}
}
// 使用:{}
println!("{}", Person { name: "张三".into(), age: 18 });
3. 外部类型无法直接实现 Display?用 Newtype 包装
rust
struct Array(Vec<i32>);
impl fmt::Display for Array {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "数组:{:?}", self.0)
}
}
四、高级格式化语法(万能格式手册)
1. 位置参数
rust
println!("{1} {0}", "a", "b"); // 输出 b a
2. 具名参数
rust
println!("{name}", name = "张三");
3. Rust 1.58+ 直接捕获环境变量(超级好用)
rust
let name = "张三";
println!("{name}"); // 直接用变量名!
五、宽度、对齐、填充(格式化表格必备)
左对齐 < / 右对齐 > / 居中 ^
rust
println!("{:<5}", "x"); // 左对齐:x____
println!("{:>5}", "x"); // 右对齐:____x
println!("{:^5}", "x"); // 居中:__x__
指定填充字符
rust
println!("{:-<5}", "x"); // x----
数字补 0
rust
println!("{:05}", 42); // 00042
六、精度控制
浮点数保留小数
rust
println!("{:.2}", 3.14159); // 3.14
字符串截取长度
rust
println!("{:.3}", "hello"); // hel
七、进制输出(调试神器)
rust
println!("{:#b}", 27); // 二进制 0b11011
println!("{:#o}", 27); // 八进制 0o33
println!("{:#x}", 27); // 小写十六进制 0x1b
println!("{:#X}", 27); // 大写十六进制 0x1B
八、指针地址输出
rust
let v = vec![1,2,3];
println!("{:p}", v.as_ptr()); // 输出内存地址
九、转义输出
想打印 { 和 }:
rust
println!("{{}}"); // 输出 {}
println!("\"Hello\""); // 输出 "Hello"
十、一张图记住 Rust 输出体系
text
标准输出:print! / println!
错误输出:eprint! / eprintln!
字符串生成:format!
占位符:
{} = Display(用户展示)
{:?} = Debug (调试)
{:#?} = 美化调试
格式控制:
对齐:< > ^
填充:0 或自定义符号
精度:.2 .4
进制:b o x X
总结(最核心 4 条)
- 日常打印用
println!,构造字符串用format! - 给用户看用
{},调试用{:?} - 复杂结构体必须加
#[derive(Debug)] - Rust 1.58+ 可直接
println!("{var}")