什麼是元編程?
元編程 = 編寫、操縱程式的程式。前綴 "meta-" 意為「超級」、「關於……的」。
- 傳統編程:運算動態,程式靜態。
- 元編程:運算與程式結構雙動態,程式可作為資料被生成、修改、推理。
經典範例:C++ 模板元編程計算階乘
template <int N>
struct factorial {
enum { value = N * factorial<N-1>::value };
};
template <>
struct factorial<0> { enum { value = 1 }; };
// 編譯期計算:factorial<5>::value 等同於 120
階乘在編譯期完成,編譯器生成新代碼並執行。
元編程解決什麼問題?
案例:動態文檔解析器
需求:用戶自定義文檔格式,隨時變更。傳統手寫解析器:開發慢、除錯難、變更導致重新編譯部署。
元編程方案:根據格式規格自動生成解析器代碼。Lex/Yacc、ANTLR 等編譯器生成器即是此類工具。
領域特定語言(DSL)與語言導向編程(LOP)
- DSL:針對特定領域的小語言(如 HQL、SQL、正則表達式),屬第 4 代語言(VHLL)。
- LOP:建立 DSL 體系後,直接用 DSL 開發系統,盡量不寫通用語言代碼。
- 流程:DSL →(編譯器生成器/元編程)→ 通用語言 → 機器碼。

優勢:DSL 更簡單、抽象、接近自然語言,開發效率高;業務分析師可審查 DSL 代碼邏輯,跨越溝通鴻溝。
元編程的廣泛應用
- IDE 向導/拖放生成代碼。
- UML 模型轉代碼。
- JSP → Servlet 轉換。
- Spring/Hibernate/XDoclet 從註解/配置生成代碼。
- 自動生成重複代碼:用 AWK/Perl/Python + 模板引擎,生成代碼的代碼(元程式)納入版控,數據源版控,靈活且可追蹤。
- 動態修改程式結構:突破靜態語言限制(Java/C++ 無法運行期加欄位/方法),動態語言通過
eval、define_method 等實現。
元編程 vs. 產生式編程
| 維度 | 元編程 | 產生式編程 |
| 核心關注 | 生成代碼的可執行性(編譯期/運行期皆可執行) | 代碼生成本身 |
| 靜態形式 | 編譯期生成源碼/位元碼 | 編譯期生成源碼 |
| 動態形式 | 運行期修改程式結構 | 通常不包含 |
元程式的最高級特質
- 將程式視為資料,具備自覺性、自適應性、智能性。
- 理論上可無限遞迴(程式的程式的程式……)。
- 願景:機器人自我學習、自我完善、生產新機器人(智能繁衍)。
IDE 依賴症警示
滑鼠點擊生成的代碼行為無法版控、難以重現;真正的工程師應掌握無需 IDE 也能編譯、除錯、部署的能力。日誌與單元測試優於互動式除錯。
課後思考
- 嘗試用 ANTLR 定義一個簡單 DSL 並生成 Java 解析器。
- 在專案中識別重複代碼模式,編寫腳本自動生成。
- 探索 Groovy 的
metaClass、ExpandoMetaClass 動態元編程能力。
- 閱讀《Generative Programming》原文版。