格式化輸出#
Rust 的 println! 巨集使用格式字串控制輸出的樣式,格式字串中的 {} 是佔位符。
1. 基本輸出#
{} 依序填入後面的參數:
1
2
3
4
5
| fn main() {
let name = "Rust";
let year = 2015;
println!("{} 誕生於 {} 年", name, year); // Rust 誕生於 2015 年
}
|
Rust 1.58 以後,可以在 {} 裡直接寫變數名稱:
1
2
3
4
| fn main() {
let x = 42;
println!("{x}"); // 42
}
|
{} 內 只能放變數名稱 ,不能放方法呼叫或運算式,需要計算的值必須作為獨立參數傳入:
1
2
3
4
5
6
7
| fn main() {
let s = String::from("hello");
println!("{}", s.len()); // 正確:5
println!("{}", s.to_uppercase()); // 正確:HELLO
// println!("{s.len()}"); // 編譯錯誤!
}
|
這和 Python f-string(f"{s.len()}")或 Kotlin("${s.length}")不同——Rust 格式字串不支援任意表達式。
2. 格式符#
格式符寫在 {} 的冒號後面,語法為 {變數:格式符},例如 {n:b} 表示以二進位輸出變數 n。
:b、:o、:x、:X 分別輸出二進位、八進位、十六進位;加上 # 前綴會顯示進位標記:
1
2
3
4
5
6
7
8
9
10
11
| fn main() {
let n = 255;
println!("{n}"); // 255 (十進位)
println!("{n:b}"); // 11111111 (二進位)
println!("{n:o}"); // 377 (八進位)
println!("{n:x}"); // ff (十六進位小寫)
println!("{n:X}"); // FF (十六進位大寫)
println!("{n:#b}"); // 0b11111111(加前綴)
println!("{n:#o}"); // 0o377
println!("{n:#x}"); // 0xff
}
|
浮點數精度#
:.N 指定小數點後幾位,多餘的位數會四捨五入:
1
2
3
4
5
6
7
| fn main() {
let f = 3.14159;
println!("{f}"); // 3.14159(預設,保留全部)
println!("{f:.0}"); // 3
println!("{f:.2}"); // 3.14
println!("{f:.4}"); // 3.1416(四捨五入)
}
|
精度也可以和欄位寬度組合:{:8.2} 表示欄寬 8、小數點後 2 位:
1
2
3
| fn main() {
println!("{:8.2}", 3.14159); // " 3.14"(欄寬 8,靠右)
}
|
欄位寬度與對齊#
數字指定最小欄位寬度,不足的地方補空白。
< 靠左、> 靠右(數字預設靠右、字串預設靠左)、^ 置中:
1
2
3
4
5
6
7
8
| fn main() {
println!("{:<10}", "hello"); // "hello "(靠左)
println!("{:>10}", "hello"); // " hello"(靠右)
println!("{:^10}", "hello"); // " hello "(置中)
println!("{:>8}", 42); // " 42" (靠右)
println!("{:<8}", 42); // "42 " (靠左)
}
|
用指定字元填充(把填充字元放在對齊符號前):
1
2
3
4
| fn main() {
println!("{:0>5}", 42); // "00042"(補零,靠右)
println!("{:*^10}", "hi"); // "****hi****"(補星號,置中)
}
|
Debug 格式#
:? 使用 Debug 格式,可以印出陣列、元組等複合型別;:#? 加上縮排換行,結構複雜時更易閱讀:
1
2
3
4
5
6
7
| fn main() {
let arr = [1, 2, 3];
println!("{arr:?}"); // [1, 2, 3]
let tup = (42, "hello", true);
println!("{tup:?}"); // (42, "hello", true)
}
|
自訂結構體需加上 #[derive(Debug)] 屬性才能使用 :?:
1
2
3
4
5
6
7
8
9
10
11
12
| #[derive(Debug)]
struct Point { x: i32, y: i32 }
fn main() {
let p = Point { x: 1, y: 2 };
println!("{p:?}"); // Point { x: 1, y: 2 }
println!("{p:#?}"); // 格式化縮排:
// Point {
// x: 1,
// y: 2,
// }
}
|
速查表#
| 格式符 | 意義 | 輸出範例 |
|---|
{} | 預設顯示 | 255 |
{:b} | 二進位 | 11111111 |
{:o} | 八進位 | 377 |
{:x} | 十六進位小寫 | ff |
{:X} | 十六進位大寫 | FF |
{:#x} | 十六進位加前綴 | 0xff |
{:.2} | 小數點後 2 位 | 3.14 |
{:8} | 欄寬 8,靠右 | 255 |
{:<8} | 欄寬 8,靠左 | 255 |
{:^8} | 欄寬 8,置中 | 255 |
{:08} | 欄寬 8,補零 | 00000255 |
{:?} | Debug 格式 | [1, 2, 3] |
{:#?} | Debug 縮排格式 | 多行縮排輸出 |
Reference#
https://doc.rust-lang.org/std/fmt/index.html