学习笔记: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::Writewriteln!: 与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 ?=>Debugx?=>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必须自己实现。
实现示例:
| |