Skip to content

打印和格式化

标准输出

控制台打印: 这是最常用的方式,将内容直接显示在屏幕上,适合用户交互、调试信息等.

换行说明适用场景
print!输出内容但不换行进度条、提示输入
println!输出内容并自动换行最常用的常规打印
dbg!打印文件名、行号及表达式的值快速调试,会夺取所有权并返回值

dbg!(): 是转移,并返回所有权(值),可以在函数最后一行使用,不加分号,相当于即打印又返回值

标准错误

错误信息打印: 当程序出错或需要输出日志(不希望被重定向拦截)时使用.

换行说明适用场景
eprint!输出到标准错误流(stderr)错误提示前缀
eprintln!输出到标准错误并换行报错、程序异常提示

使用 eprintln! 即使别人把你的程序结果存入文件,错误信息依然能直接显示在屏幕上

打印占位符

核心特性类 (Traits)

这组最常用,决定了如何"表现"一个变量.

  • {}: (Display) -- 用于人看的,要求类型实现 std::fmt::Display(如数字、字符串).
  • {:?}: (Debug) -- 紧凑输出,用于开发者看的(dbg!默认使用).要求类型实现 std::fmt::Debug(大多数结构体用 #[derive(Debug)] 后可用).
  • {:#?}: (Debug) -- 美化打印.会带缩进和换行,适合查看复杂的结构体.
  • {:p}: (Pointer) -- 指针地址,以十六进制显示内存位置.
  • 使用 {var} 内联捕获语法时只支持本地变量名,不支持字段访问(如 {x.name} 无效)
  • 使用 println!("{}", expr) 形式则不受此限制,参数部分可以是任意表达式(如 x.name1 + 2)

数值进制类

用于将整数转换成特定的数制显示.

  • {:b}: Binary -- 二进制.
  • {:o}: Octal -- 八进制.
  • {:x} / {:X}: Hex -- 十六进制(小写/大写).
  • {:e} / {:E}: Exponential -- 科学计数法(小写/大写).

填充与对齐

用于控制输出内容的宽度和位置(常用于打印表格).

  • {:5}: 设置最小宽度为 5(默认左对齐).
  • {:>5}: 右对齐,宽度为 5.
  • {:<5}: 左对齐,宽度为 5.
  • {:^5}: 居中对齐,宽度为 5.
  • {:0>5}: 用 0 填充左侧空间(常用于流水号).
  • {:*^5}: 用 * 填充两侧空间,使其居中.

精度与符号

常用于处理浮点数或特定数值前缀.

  • {:.2}: 保留 2 位小数.
  • {:+}: 强制显示正负号(例如 +42).
  • {:#x}: 带前缀的十六进制(输出 0x1a 而不是 1a).
rust
let n = 255;
println!("指针: {:p}", &n);      // 0x7ffee6b5a5e4
println!("十六进制: {:#x}", n); // 0xff
println!("二进制: {:b}", n);    // 11111111
println!("对齐: |{:^10}|", n);  // |   255    |

println! 系列宏格式规则

  • 普通占位符: println!("Hello, {}!", "world") -> Hello, world!
  • 位置参数: println!("{1}, {0}", "world", "hello") -> hello, world!
  • 命名参数: println!("{name} is {age}", name="Alice", age=30) -> Alice is 30
  • 格式化属性(补零、对齐、精度):
    • println!("{:03}", 5) -> 005
    • println!("{:.2}", 3.14159) -> 3.14
  • Debug 打印: println!("{:?}", vec![1, 2]) -> [1, 2]

println!format!panic!write! 以及 debug_assert! 等宏,调用的都是 Rust 内部同一个格式化引擎 std::fmt,只是它们的参数解析和输出目标不同.

format! 格式化到字符串

这些宏不打印到屏幕,不直接显示,而是将结果"存起来".

说明返回值适用场景
format!格式化内容并返回一个字符串String 对象拼接字符串、构造动态文本
write!将内容写入一个"缓冲区"Result写入文件、写入内存 Buffer

println!()eprintln!()

这两个宏的底层区别在于它们指向的输出流(Stream)不同.虽然它们都能把文字打在屏幕上,但用途完全不同.

  1. 核心区别

    特性println!()eprintln!()
    全称Print LineError Print Line
    输出流标准输出 (stdout)标准错误 (stderr)
    用途输出程序的正常业务结果输出错误信息、调试日志、状态更新
    重定向行为经常被重定向到文件通常保持留在屏幕上,不被重定向
  2. 为什么要分两个?(重定向场景)

    在 Linux 或 macOS 终端中,用户经常会把程序的输出保存到文件:

    bash
    $ cargo run > output.txt
    
    $ cargo run 2> error.txt #(2> 代表重定向错误流),这时候错误才会进 error.txt
    • 使用 println!(): 所有内容都会进 output.txt.如果程序报错了,错误信息也会进文件,用户在屏幕上什么都看不到,会很困惑.
    • 使用 eprintln!(): 即使你把正常输出重定向到了文件,eprintln!() 的内容依然会显示在屏幕上.这样用户就能立刻看到报错,而不会污染 output.txt, 而是进入 error.txt.

    重定向符号

    符号代表的流默认行为适用场景用法示例
    > / 1>标准输出 (stdout)println! 或正常结果存入文件存储程序运行的数据结果cargo run > output.txt
    2>标准错误 (stderr)eprintln! 或报错信息存入文件存储程序的报错日志cargo run 2> error.txt
    &>全部输出同时将 stdout 和 stderr 存入同一个文件完整记录程序运行的所有痕迹cargo run &> all.txt
  3. 使用建议

    • println!(): 只用来打印用户请求的数据(比如搜索结果、计算后的数字).
    • eprintln!(): 用来打印"正在执行第 1 步..."、"发生网络错误"或"缺少参数"等非业务数据.

小贴士: 在开发时,如果你习惯用打印大法调试,建议改用 dbg!() 宏,它会自动带上文件名和行号,而且它走的是 stderr(和 eprintln!() 一样),不会干扰你的正常程序输出.

println!()dbg!()

  • println! 宏的设计基于"格式化字符串",它的第一个参数必须是字符串字面量 "" (格式模板 "{}"), 一个萝卜一个坑,参数数量和格式模板中的占位符数量必须匹配,不支持空括号.
  • dbg! 宏的设计基于"表达式",它的第一个参数可以是任何表达式、变量或留空(默认打印最后一个表达式的值),参数数量不受限制,支持空括号(会打印当前代码位置).
特性println!dbg!
第一个参数必须是字符串字面量 "{}"可以是任何表达式、变量或留空
参数数量1 个(纯文本)或多个(带占位符)0 个、1 个或多个(多参数视为元组)
是否支持空括号不支持(println!() 仅打印换行)支持(dbg!() 打印当前代码位置)
主要用途最终用户输出(定制化格式)开发者调试(快速看值和位置)

基于 MIT 协议发布