輸出巨集
Rust 的列印(輸出)功能,是由 std::fmt 模組內的一連串巨集所實作,以下說明常用的巨集:
format!:將格式化文字寫入字串print!:將內容輸出至主控台(標準輸出)println!:用法同print!,結尾會自動換行eprint!:將內容輸出至標準錯誤串流eprintln!:用法同eprint!,結尾會自動換行
名稱結尾帶有 ln 的巨集,都會自動加上換行符號,輸出完畢後換行。
開頭為 e 代表 error,專門用來輸出錯誤訊息。
以上這些巨集的格式化語法完全相同,而且 Rust 會在編譯階段檢查格式化程式碼是否合法。
使用範例
基礎佔位符 {}
{} 是通用佔位符,會依照順序替換成後方傳入的參數,並自動轉換為字串輸出。
fn main() {
println!("{} days", 31);
// 輸出:31 days
}Code language: JavaScript (javascript)
位置參數
可以在 {} 內填入數字索引(從 0 開始計算),手動指定要使用哪一個參數,也支援重複使用參數、調換參數順序。
fn main() {
println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");
// 輸出:Alice, this is Bob. Bob, this is Alice
}Code language: JavaScript (javascript)
從上面範例可以看出,參數索引不一定要按照 0、1、2……的順序排列,可以自由調換。後方傳入的參數 “Alice”、”Bob”,其中 Alice 對應索引 0,Bob 對應索引 1。
具名參數
如果覺得使用索引不夠直觀,可以改用具名參數。在格式化字串中使用 {參數名稱},呼叫時則以 參數名稱=數值 的形式傳入,參數順序不受限制,可讀性也更高。
fn main() {
println!("{subject} {verb} {object}",
object="the lazy dog",
subject="the quick brown fox",
verb="jumps over");
// 輸出:the quick brown fox jumps over the lazy dog
}Code language: JavaScript (javascript)
簡單來說,就是幫後方的參數設定名稱,接著在格式化字串裡直接使用 {參數名稱} 來對應,寫起來更加淺顯易懂。
進位制格式化(:格式符)
在佔位符內加上 : 與格式字元,就能將數字轉換為二進位、八進位、十六進位等不同進位制。
:b:二進位:o:八進位:x:小寫十六進位
fn main() {
println!("十進位: {}", 69420); // 69420
println!("二進位: {:b}", 69420); // 10000111100101100
println!("八進位: {:o}", 69420); // 207454
println!("十六進位:{:x}", 69420); // 10f2c
}Code language: JavaScript (javascript)
寬度對齊與補位
1 靠右對齊(>寬度)
{:>n} 代表整體顯示寬度為 n,內容會靠右對齊,左側補上空格。
fn main() {
println!("{number:>5}", number=1);
// 總寬度 5,左側補 4 個空格 → 輸出: 1
}Code language: JavaScript (javascript)

2 補零對齊
在對齊符號前方加上 0,就會改用數字 0 取代空格來補位。
:0>5:靠右對齊,左側補 0:0<5:靠左對齊,右側補 0
fn main() {
println!("{number:0>5}", number=1); // 靠右對齊並補零 → 00001
println!("{number:0<5}", number=1); // 靠左對齊並補零 → 10000
}Code language: JavaScript (javascript)
除了數字 0 以外,也可以使用其他字元補位。以下範例使用大寫英文字母 A 來填補空位。
fn main() {
println!("{number:A>5}", number=1); // 靠右對齊補 A → AAAAA1
println!("{number:A<5}", number=1); // 靠左對齊補 A → 1AAAAA
}Code language: PHP (php)

3 動態寬度(變數名稱$)
不用把寬度寫死,透過 變數名稱$ 參考外部的具名參數或變數,就能動態控制顯示寬度。
也就是顯示寬度可由變數控制,而非直接在程式碼中固定數值。
fn main() {
// 方式一:搭配具名參數
println!("{number:0>width$}", number=1, width=8);
// 方式二:直接取用區域變數(Rust 1.58 以上版本支援)
let number: f64 = 1.0;
let width: usize = 8;
println!("{number:>width$}"); // 輸出: 1
}Code language: JavaScript (javascript)

編譯期參數檢查
Rust 會在編譯階段檢查佔位符數量與傳入參數數量是否一致,若參數不足,會直接產生編譯錯誤。
fn main() {
// 兩個佔位符,但只傳入一個參數,編譯失敗
println!("My name is {0}, {1} {0}", "Bond");
// 修正:補上參數 "James"
println!("My name is {0}, {1} {0}", "Bond", "James");
}Code language: JavaScript (javascript)

編譯器會提示 {1} 位置無效,因為後方僅傳入一個參數。
錯誤:參考了不存在的位置參數 1(目前僅傳入 1 個參數)
--> D:\rustdemo\hello.rs:3:29
|
3 | println!("My name is {0}, {1} {0}", "Bond");
| ^
|
= 提示:位置參數從 0 開始編號
錯誤:編譯中止,共 1 個錯誤Code language: JavaScript (javascript)
自訂型別的格式化限制
預設情況下,{} 僅能用來格式化有實作fmt::Display 特徵的型別。自訂結構體預設並沒有實作此特徵,直接使用 {} 列印會造成編譯錯誤。
fn main() {
struct Structure(i32);
// 下方程式無法通過編譯
println!("{}", Structure(3));
}Code language: JavaScript (javascript)

錯誤[E0277]:結構體 `Structure` 未實作 `std::fmt::Display` 特徵
--> D:\rustdemo\hello.rs:4:20
4 | println!("{}", Structure(3));
| -- ^^^^^^^^^^^^ 此型別無法使用預設格式器輸出
| |
| 此格式參數要求型別必須實作 Display 特徵
提示:結構體 `Structure` 並未實作 `std::fmt::Display` 特徵
--> D:\rustdemo\hello.rs:2:2
2 | struct Structure(i32);
| ^^^^^^^^^^^^^^^^
補充說明:在格式字串中,可以試著改用 `{:?}`(或 `{:#?}` 美化輸出)
編譯中止,共 1 個錯誤。
想瞭解此錯誤詳情,可執行指令:rustc --explain E0277Code language: JavaScript (javascript)
* 1 如果要正常輸出結構體,就必須實作 Display 特徵(先大致理解即可,後續會詳細說明)
use std::fmt;
struct Structure(i32);
// 為結構體實作 Display 特徵
impl fmt::Display for Structure {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// self.0 用來存取元組結構體內的 i32 數值
write!(f, "數值:{}", self.0)
}
}
fn main() {
println!("{}", Structure(3));
}Code language: PHP (php)
* 2 暫時除錯 → 使用除錯格式 {:?} / {:#?}
此方式適合開發者除錯使用。若只是單純想查看結構體內的數值,並非正式發布版本,可以使用 Debug 除錯特徵。
Rust 預設會幫自訂型別實作除錯特徵 Debug,搭配 {:?} 就能直接列印內容:
#[derive(Debug)]
#[allow(dead_code)] // 關閉未使用程式、欄位的警告
struct Structure(i32);
fn main() {
println!("{:?}", Structure(3));
println!("{:#?}", Structure(3));
}Code language: PHP (php)
* std::fmt 兩大核心格式化特徵
std::fmt 模組內包含多個控制文字顯示的特徵,以下介紹兩個最常用的:
- fmt::Debug 搭配佔位符
{:?},專門用於除錯情境輸出內容。 - fmt::Display 搭配佔位符
{},呈現格式規範、友善的內容,主要給一般使用者觀看。
標準函式庫內建的型別,預設都已實作這兩種特徵,可以直接列印;但自訂型別無法直接使用,必須手動實作對應的特徵。
當一個型別實作 fmt::Display 之後,會自動連帶實作 ToString 特徵,支援將該型別轉換成字串。
#[allow(dead_code)]
#[allow(dead_code)] 是程式屬性,作用於緊接在後方的程式項目,用途是關閉「程式未使用」的警告訊息。
參考以下範例:
fn main() {
struct Structure(i32);
// 下方程式會發生錯誤,因此先行註解
//println!("{}", Structure(3));
}Code language: JavaScript (javascript)
由於列印程式碼會報錯而被註解,此時執行程式,
warning: struct `Structure` is never constructed
--> D:\rustdemo\hello.rs:2:12
|
2 | struct Structure(i32);
| ^^^^^^^^^
|
= note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default
warning: 1 warning emitted
Code language: JavaScript (javascript)

編譯器就會出現以上警告,原因是結構體 Structure 定義後從未被使用。如果想要隱藏這則警告,就可以加上這個標註。
fn main() {
#[allow(dead_code)]
struct Structure(i32);
// 下方程式會發生錯誤,因此先行註解
//println!("{}", Structure(3));
}Code language: PHP (php)
浮點數設定小數位數
定義變數 pi = 3.141592,透過格式化輸出保留三位小數,列印結果為:Pi is roughly 3.142。
fn main() {
let pi = 3.141592;
println!("Pi is roughly {:.3}", pi);//3.142
println!("Pi is roughly {0}", pi); //3.141592
}Code language: JavaScript (javascript)