2017:生態成熟之年——生產力 Roadmap 與小步快跑#
事件#
2017 年,Rust 核心團隊公佈年度 Roadmap,定調為「生產力、成熟度」:語言功能讓位給人體工學與工具鏈改進。全年以 1.x 小步快跑模式發佈(每六週一版),生態快速成熟——serde、tokio 前身(futures)、wasm 支援相繼出現。
為何重要#
- 六週發佈節奏:類似 Chrome 模式——新特性先進 nightly,穩定後按節奏釋放,避免「大版本斷裂」。這讓 Rust 能兼顧 1.0 的穩定承諾與持續演化。
- derive 生態爆發:
serde的#[derive(Serialize, Deserialize)]展示了「程序性宏(proc-macro)」的威力——特性在 1.15(2017/2)穩定,成為 Rust 生態最重要的元程式設計基礎。 - WebAssembly 支援:Rust 成為最早一等支援 wasm 的系統語言,開啟「Rust 到瀏覽器」的新戰場。
- 借用檢查器(NLL)預告:非詞法生命週期(Non-Lexical Lifetimes)開始研發,讓借用檢查更聰明、更少誤報。
理論與實用原因#
- 理論原因:proc-macro 基於「程式碼即資料」的元程式設計傳統(Lisp macro),但以 token stream + 型別化的 AST 實現衛生性;NLL 則把生命週期從「詞法作用域」放寬為「實際使用範圍」的圖論分析。
- 實用原因:serde 前的手动序列化樣板龐大;NLL 前借用檢查器把「變數離開作用域」當成借用結束,導致大量合法程式被誤判——這是使用者最大的痛點。
程式範例#
proc-macro 的威力——serde 的 derive,序列化一行搞定:
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct User {
name: String,
age: u8,
}
fn main() {
let u = User { name: "Ada".into(), age: 36 };
let json = serde_json::to_string(&u).unwrap();
// {"name":"Ada","age":36}——Serialize/Deserialize 全自動生成
let back: User = serde_json::from_str(&json).unwrap();
}
沒有 derive 的手動樣板(serde 之前的世界):
impl Serialize for User {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
let mut st = s.serialize_struct("User", 2)?;
st.serialize_field("name", &self.name)?; // 每個欄位手寫
st.serialize_field("age", &self.age)?;
st.end()
}
}
// 欄位一多就是數十行樣板,還容易寫錯欄位名——derive 從根上消滅
NLL 之前後——借用檢查器不再誤判合法程式:
let mut v = vec![1, 2, 3];
let last = v.last(); // 借用開始
println!("{:?}", last); // 借用最後一次使用
v.push(4); // NLL:這裡借用已結束,OK
// NLL 之前:編譯錯誤——借用被誤判持續到作用域結尾
彌補了什麼缺陷#
彌補了 Rust「序列化等樣板程式碼過多(proc-macro 之前)」與「借用檢查器過度保守、拒絕合法程式(NLL 之前)」的缺陷——2017 是「補人體工學、不補能力」的一年。