Rust變量為啥要設計成默認不可變?
Rust 定義變量默認是不可變的,如果可變,需要顯式關鍵字 mut 聲明。
// 不允許修改
let x = 12;
// 允許修改
let mut y = 13;
如果你對不允許修改的變量進行修改,是會直接編譯報錯的。

那么 rust 為啥要這樣設計呢?
1. 內存安全(Memory Safety)無需垃圾回收器(GC)
Rust 的核心目標是:在不依賴 GC 的前提下保證內存安全。
而不可變變量(let x = ...)是達成這個目標的重要手段。
// 編譯錯誤 - 防止意外修改
let x = 5;
x = 10; // 編譯器阻止
// 必須顯式聲明可變性
let mut y = 5;
y = 10; // OK
- 如果一個變量不可變,那么:
- 你不能隨意修改它的值;
- 編譯器可以確信:只要這個變量存在,其值就是一致的;
- 多線程訪問中,不可變數據天然是線程安全的(無需加鎖);
- 編譯器無需追蹤誰在修改它 → 避免數據競爭。
底層原理:編譯器在構建“借用檢查器”(borrow checker)時,可以將不可變綁定視為只讀引用的生命周期,提升靜態分析能力。
2. 易于靜態分析與編譯優化
不可變性讓 Rust 編譯器在編譯期間更容易進行靜態分析與優化:
- 不可變數據不會變化 → 編譯器可以提前內聯、緩存、優化;
- 編譯器能推導出更精準的生命周期與借用范圍;
- 代碼行為更可預測,避免未定義行為(undefined behavior)。
舉例:LLVM 后端可以對不可變變量做 aggressive constant folding(通過編譯器優化技術對程序中重復出現的常量表達式進行折疊處理,以減少運行時計算量并優化代碼體積)、值傳播、死代碼消除等。
let x = expensive_calculation();
// 編譯器知道 x 不會改變,可以:
// 1. 將 x 存儲在寄存器中
// 2. 消除重復的內存讀取
// 3. 進行常量傳播優化
use_value(x);
use_value(x); // 4.編譯器可以重用之前的值
3. 避免數據競爭(Data Race)
Rust 中的數據競爭是編譯錯誤,而不是運行時錯誤。默認不可變正好是最好的保護:
- 數據競爭是指:兩個線程同時訪問同一變量,且至少一個是寫;
- 默認不可變意味著:你要寫變量必須顯式
mut標注,或者加鎖; - 所有“可變”的行為都必須顯式 → 更容易在代碼審查中發現問題。
比如在Java語言中,這段代碼編譯是不會報錯的,但是輸出結果無法保證,可能為 1(本應是 2)。
這種問題 運行時才暴露問題,可能非常隱蔽且難以調試。
public class RaceConditionExample {
private static int counter = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
counter++; // 不是原子操作
});
Thread t2 = new Thread(() -> {
counter++; // 不是原子操作
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Counter: " + counter);
}
}
但是在rust 中會直接編譯失敗。
use std::thread;
fn main() {
let mut counter = 0;
let handle1 = thread::spawn(|| {
counter += 1; // ? 編譯失敗
});
let handle2 = thread::spawn(|| {
counter += 1; // ? 編譯失敗
});
handle1.join().unwrap();
handle2.join().unwrap();
}
運行報錯:

Rust 編譯器發現你把一個非線程安全的可變變量 counter 移入了兩個線程閉包中,而沒有同步機制,于是直接編譯錯誤。
4. 表達設計意圖,提升可讀性與可維護性
不可變變量也是一種語義提示:
let x = 5→ 表示 x 不會改變;let mut x = 5→ 表示 x 的值會變化。
這種強制標記有助于代碼維護者理解變量生命周期與職責。
5. 默認安全(safe by default)
Rust 的設計哲學之一是:安全默認(safe by default),也就是說:
- 只有當程序員顯式請求“危險行為”(如
unsafe、mut、裸指針等)時才打開風險; - 變量默認不可變 → 編譯器可以保證只讀訪問不會引起內存錯誤;
- 需要寫權限時,你得自己“承擔責任”去標明。
浙公網安備 33010602011771號