学习笔记:Rust字符串打印格式化输出详解
总结摘要
本文详细介绍了 Rust 中的字符串格式化输出功能,主要通过 std::fmt 模块中的宏实现,如 format!、print!、println! 等。文章详细讲解了格式化规则,包括位置参数、具名参数、指定宽度、填充与对齐、格式化标识、精度控制、转义以及语法顺序。此外,还介绍了 Debug 和 Display 两个重要的格式化 trait,以及如何为自定义类型实现 Display。这些内容帮助开发者更好地理解和使用 Rust 的格式化功能。
Rust语言的打印操作主要是通过在std::fmt
里面定义的一系列宏来处理。主要包括:
format!
: 将格式化文本存入字符串。print!
: 与format!
类似,但是把文本输出到控制台(io::stdout
)println!
: 与print!
类似,但是输出结果末尾会追加换行符。eprint!
: 与format!
类似,但是把文本输出到标准错误(std::stderr
)。eprintln!
: 与eprint!
类似,但是输出结果末尾会追加换行符。write!
: 与format!
类似,但是把文本输出到&mut io::Write
writeln!
: 与write!
,但是输出结果末尾会追加换行符。
这些宏都会以一致的规则对文本进行解析,格式化的正确性会在编译器进行检查。
格式化规则
位置参数
每个格式化参数可以按照顺序进行格式化,也可以按照指定的顺序对其进行格式化。
{}
: 没有指定索引位置,会按照参数迭代逐个使用{n}
: 指定了索引位置,就会使用指定索引的参数
|
|
具名参数
对于已经存在的变量,可以按照变量名字输出。
如果不存在,也可以进行指定名称。
|
|
格式化参数
我们可以指定一些格式化的参数,来对格式化的输出进行个性化的定制。
指定宽度
需要注意的是,这里指定的是最小宽度,如果字符串不足宽度会进行填充,如果超出并不会截断。
{:n}
: 通过数字直接指定宽度,比如{:5}
{:n$}
: 通过参数索引指定宽度,比如{:1$}
{:name$}
: 通过具名参数指定宽度,比如{:width$}
|
|
填充与对齐
在格式化字符串内,一般按照 : + 填充字符 + 对齐方式
来排列。
[fill]<
: 左对齐[fill]^
: 居中对齐[fill]>
:右对齐
非数字时,默认情况下填充使用空格+左对齐。
数字时,默认情况下填充使用空格+右对齐。
特别要注意的,某些类型可能不会实现对齐。特别是对于Debug
trait,通常不会实现该功能。确保应用填充的一种好方法是格式化输入,再填充此结果字符串以获得输出。
|
|
格式化标识
我们还可以使用一些格式化标识对字符串进行格式化。
+
: 数字打印符号,默认情况下数字不会打印正号,加了该标识符可以强制打印正负号。#?
: 打印Debug格式,同时会添加换行符和缩进。#x
: 以十六进制小写形式打印#X
: 以十六进制大写形式打印#b
: 以二进制形式打印#o
: 以八进制形式打印
|
|
精度控制
这里的精度控制其实就是最大宽度,超出将会进行截断。
对于整数类型,这里会被忽略。
对于浮点类型,指示小数点后打印多少位。
.n
: 整数n就是精度.n$
: 使用参数n作为精度,这里也可以是具名参数。.*
: 与两个格式输入关联,第一个输入是要保存的精度,第二个是要打印的值。
|
|
转义
字面量字符{
和}
可以通过添加相同字符进行转义,即{
字符使用{{
进行转义,而}
字符使用}}
进行转义。
语法顺序
|
|
格式化的trait
- nothing =>
Display
?
=>Debug
x?
=>Debug
带有小写十六进制整数X?
=>Debug
带有大写十六进制整数o
=>Octal
, 八进制x
=>LowerHex
, 小写十六进制X
=>UpperHex
, 大写十六进制p
=>Pointer
, 指针b
=>Binary
, 二进制e
=>LowerExp
,小写e的科学计数法E
=>UpperExp
,大写E的科学计数法
Debug trait
Debug
是为开发者调试打印数据结构所设计的,在使用的时候,Debug 用 {:?}
来打印。在大多数情况下,建议使用 #[derive(Debug)]
派生宏直接生成就足够了。
Display trait
Display
是给用户显示数据结构所设计的,在使用的时候,Display 用 {}
打印。自定义类型的Display
必须自己实现。
实现示例:
|
|