Rust 输出到命令行

println! 的格式占位符、调试输出、以及格式化家族。

Beginner
Key Points`{}` 走 `Display`,`{:?}` 走 `Debug`,`{:#?}` 是美化版 Debug。

四种输出宏

MacroTargetNewline
print!stdout不换行
println!stdout换行
eprint!stderr不换行
eprintln!stderr换行
Rust
fn main() {
    print!("不换行");
    println!(",然后换行");
    eprintln!("这条去 stderr");
}
Output
不换行,然后换行
这条去 stderr

占位符

Rust
fn main() {
    let name = "Rust";
    let n = 42;
    let pi = 3.14159;

    println!("{} 版本 {}", name, n);
    println!("{0} {0} {1}", "重复", "参数");
    println!("{name} 可以直接插变量");
    println!("{:?}", vec![1, 2, 3]);
    println!("{:#?}", vec![1, 2, 3]);
    println!("{:05}", n);
    println!("{:.2}", pi);
    println!("{:>8}|{:<8}|{:^8}", "右", "左", "中");
    println!("{:b} {:o} {:x} {:X}", 255, 255, 255, 255);
    println!("{:e}", 12345.678);
}
Output
Rust 版本 42
重复 重复 参数
Rust 可以直接插变量
[1, 2, 3]
[
    1,
    2,
    3,
]
00042
3.14
       右|左      |   中   
11111111 377 ff FF
1.2345678e4

Inline {name} arrived in Rust 1.58 — shorter than println!("{}", name) and impossible to mismatch. It only takes identifiers, not arbitrary expressions.

Display 与 Debug

Rust
#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p = Point { x: 1, y: 2 };

    println!("{:?}", p);
    println!("{:#?}", p);
    // println!("{}", p);   // 编译错误:Point 没有实现 Display
}
Output
Point { x: 1, y: 2 }
Point {
    x: 1,
    y: 2,
}

#[derive(Debug)] generates Debug for {:?}. Display ({}) must be written by hand — there is no universal answer for how a value should read to a human.

Rust
use std::fmt;

impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "({}, {})", self.x, self.y)
    }
}

println!("{}", Point { x: 1, y: 2 });
Output
(1, 2)

格式化到字符串

Rust
let s = format!("{} + {} = {}", 1, 2, 3);
println!("{}", s);

// 追加到已有字符串
let mut buf = String::from("结果:");
use std::fmt::Write;
write!(buf, "{}", 42).unwrap();
println!("{}", buf);
Output
1 + 2 = 3
结果:42
The number of {} must match the arguments — a mismatch is a compile error, not a runtime panic. That is where Rust's format macros beat C's printf.

Friends & Partners