RUST 学习日记 第9课 ——输入与输出
0x00 回顾
上一节主要讲解了Rust中的数值类型进行类型转换的一些要点。这节咱们来了解下Rust的输入和输出。前面用过println!
好多次了,这里详细介绍下它用法,本篇文章可能是全网最详细的Rust的输出用法讲解了。
0x01 输出(print!)
当首次接触到Rust,用他写出Hello World!
时,咱们就已经接触到输出println!
了,咱们已经知道了可以用它来输出字符串、数字等等,其实它还有很多格式化输出的方式。下来一起来了解下。
1、默认输出
println
可以直接输出字符串字面量。
示例代码:
println("hello wolrd");
代码执行结果:
Hello, world!
2、通配符
在字符串字面量中使用{}
通配符代指即将输出的值,后面依次对应输出的值。如果有多个值,中间需使用英文逗号,
分隔。
示例代码:
println!("今天是 {} 年 {} 月 {} 日", 2021, 6, 22);
代码执行结果:
今天是 2021 年 6 月 22 日
3、通配符 + 位置
输出时可以在通配符{}
中添加要输出值的位置(从0开始),来代指当前要输出哪个位置的值。
示例代码:
println!("{0} 的平方是 {0}, {0} 的相反数是 {1}", 1, -1);
代码执行结果:
1 的平方是 1, 1 的相反数是 -1
4、通配符 + 命名参数
输出时可以在通配符{}
中添加要输出值命名参数,来代指当前要输出哪个命名参数的值。
示例代码:
println!("我的名字叫{name}, 今年{age}岁, 喜欢{hobby}", hobby = "打篮球", name = "张三", age = 18);
代码执行结果:
我的名字叫张三, 今年18岁, 喜欢打篮球
5、通配符 + 对齐方式 + 对齐宽度
输出时可以在通配符{}
中添加要输出值的位置(从0开始),来代指当前要输出哪个位置的值。常用符号如下表所示:
格式 | 说明 |
---|---|
{:b} | 输出结果转为二进制 |
{:o} | 输出结果转为八进制 |
{:x} | 输出结果转为十六进制(小写) |
{:X} | 输出结果转为十六进制(大写) |
{:e} | 科学计数(小写) |
{:E} | 科学计数(大写) |
{:p} | 输出指针 |
{:?} | 打印Debug |
{:+} | 数值类型如果是整数,则前置打印+号 |
其它符号:
1、#
号——这应该算是一个补充标记符。常与其它字符连用。
格式 | 说明 |
---|---|
{:#b} | 在输出的二进制前添加0b |
{:#o} | 在输出的八进制前添加0o |
{:#x} | 在输出的十六进制前添加0x (x是小写) |
{:#X} | 在输出的十六进制前添加0x (x是小写) |
{:#?} | 带换行和缩进的Debug打印 |
2、> < ^ ——定义宽度
格式 | 说明 |
---|---|
{:6}或者{:>6} | 输出结果右对齐,6的值是usize类型 |
{:<6} | 输出结果左对齐,6的值是usize类型 |
{:^6} | 输出结果居中,6的值是usize类型 |
{:任意字符^6} | 输出结果居中,其余位置填充任意字符,6的值是usize类型 |
{:任意字符>6} | 输出结果右对齐,其余位置填充任意字符,6的值是usize类型 |
{:任意字符<6} | 输出结果左对齐,其余位置填充任意字符,6的值是usize类型 |
3、$——约束条件位置定义
格式 | 说明 |
---|---|
{:1$,"a",6} | 宽度表示符是下标为1的值(该值是usize类型) |
{1:0$,6,"a"} | 宽度表示符是下标为0的值(该值是usize类型) |
{:width$,"a",width = 6} | 使用变量名定义宽度的值 |
4、0 ——常用作整数格式化时填充宽度
格式 | 说明 |
---|---|
{:08b} | 输出8位二进制,不足8位使用0填充 |
{:08o} | 输出8位八进制,不足8位使用0填充 |
{:016x} | 输出8位十六进制,不足16位使用0填充 |
5、.N——常用作表示小数的精确值
格式 | 说明 |
---|---|
{:.3} | 小数点后精确度保留3位(不足补零,多余截断) |
{1:.0$} | 位置为1的值的精确度是位置为0的值(不足补零,多余截断) |
{:.*} | 接下来连续的两个值,第二个值的精确度是第一个值(不足补零,多余截断) |
示例代码:
let a = 31;
let b = [1, 3, 5, 7, 9];
println!("二进制 {:b}", a);
println!("八进制 {:o}", a);
println!("十六进制(小写) {:x}", a);
println!("十六进制(大写) {:X}", a);
println!("科学计数(小写) {:e}", 100000_f32);
println!("科学计数(大写) {:E}", 100000_f32);
println!("打印Debug {:?}", b);
println!("输出标点 {:+}", 5);
println!("前置符二进制 {:#b}", a);
println!("前置符八进制 {:#o}", a);
println!("前置符十六进制(小写) {:#x}", a);
println!("前置符十六进制(大写) {:#X}", a);
println!("带换行和缩进的Debug打印 {:#?}", b);
println!("使用大于号右对齐 {:>6}{:>6}{:>6}", 1, 2, 3);
println!("使用小于号左对齐 {:<6}{:<6}{:<6}", 1, 2, 3);
println!("省略大于号右对齐 {:6}{:6}{:6}", 1, 2, 3);
println!("居中对齐 {:^6}{:^6}{:^6}", 1, 2, 3);
println!("填充任意字符居中对齐 {:-^6}{:*^6}{:1^6}", 1, 2, 3);
println!("二进制8位补零 {:08b}", a);
println!("八进制8位补零 {:08o}", a);
println!("十六进制16位补零 {:016b}", a);
println!("{:1$}", "a", 6);
println!("{1:0$}", 6, "a");
println!("{:width$}", "a", width = 6);
println!("小数保留位数 {:.3} ", 0.01);
println!("小数保留位数 {1:.0$} ", 3, 0.01);
println!("{}小数保留3位数 {:.*} --- 保留4位数 {:.*} ", 0.01, 3, 0.01, 4, 0.10);
代码执行结果:
二进制 11111
八进制 37
十六进制(小写) 1f
十六进制(大写) 1F
科学计数(小写) 1e5
科学计数(大写) 1E5
打印Debug [1, 3, 5, 7, 9]
输出标点 +5
前置符二进制 0b11111
前置符八进制 0o37
前置符十六进制(小写) 0x1f
前置符十六进制(大写) 0x1F
带换行和缩进的Debug打印 [
1,
3,
5,
7,
9,
]
使用大于号右对齐 1 2 3
使用小于号左对齐 1 2 3
省略大于号右对齐 1 2 3
居中对齐 1 2 3
填充任意字符居中对齐 --1---**2***113111
二进制8位补零 00011111
八进制8位补零 00000037
十六进制16位补零 0000000000011111
Process finished with exit code 0
6、{
和}
有时可能在字符串中包含{
和}
,这里可以通过{{
输出{
,}}
输出}
。
示例代码:
println!("左边的括号 {{");
println!("右边的括号 }}");
println!("全括号 {{}}");
0x02 格式化(format!)
格式化的用法和输出的用法基本相同,它的用途是写格式化文本到字符串。上面代码的所有println!
都可以换成format!
,使用format!
常用于格式化多个变量为字符串。println
则会直接输出到屏幕。这里就不再额外介绍一次了。
0x03 输入 (Stdin)
标准输入也叫作控制台输入,是常见输入的一种。控制台输入其实很少可以用的到,这里简单介绍下了。
示例代码:
let mut input = String::new();
std::io::stdin().read_line(&mut input).expect("read_line error!");
println!("你输入的内容是 : {}", input);
解释下上面的代码,我们声明了一个可变的字符串类型的变量,然后使用了stdin
去从控制台读出输入内容保存到input
中。如果读入失败出现异常,则输出自定义错误read_line error!
。这里的字符串,错误处理,后续章节会介绍,这里了解即可。
0x04 小结
这节课主要讲了Rust的输出格式。开篇我也说了,本篇文章可能是全网最详细的Rust的输出用法讲解了。另外,print!
默认是无法打印结构体类型的。对于控制台输入的操作了解即可。不知道大家发现了没有,println!
后面有一个叹号,我也从把println!
叫做是一个函数。没错,它不是一个函数,它叫做宏。宏与函数的主要区分就是看它是不是以感叹号结尾。关于宏的知识也将会在后续章节介绍,感兴趣的同学可以提前从网上查下资料。
0x05 本节源码
009 · StudyRust - 码云 - 开源中国 (gitee.com)
下节预告——Rust的复合数据类型。