跳至主要內容
YIP NEWS
YIP NEWS

10月9日

廚房裡那面會自己照菜單的鏡子,要被收起來了

生活爐 美食生活

Dart 4.0 將徹底移除 dart:mirrors,我們把執行期反射退場這件事,翻譯成廚房裡照鏡子與提前備料的滋味故事。

刊出 (台北時間) 閱讀約 4 分鐘

2026 年 10 月 8 日,掘金上一篇談 Dart 4.0 的技術文章引發討論:按照目前計畫,Dart 3.14 會在 2026 年 11 月把 dart:mirrors 標記為 @deprecated,接著 Dart 4.0 將它完全移除。這個 Flutter 從來用不上、卻在 Dart 歷史裡活了很久的反射能力,終於要退場了。

把這件事搬進廚房,其實不難理解。

想像你開了一間小餐館,爐子上有一面神奇的鏡子。客人坐下了,報上菜名,鏡子就自己照一遍廚房,找出冰箱裡有什麼、哪個鍋還熱著、今天的高湯剩多少,然後當場拼出一道菜。聽起來很省事,對吧?dart:mirrors 做的就是這種事:程式跑起來之後,透過 MirrorSystem 去查 library、class、method、field,甚至用 InstanceMirror.invoke() 按名字呼叫方法。伺服器框架啟動時掃描所有帶路由註解的方法、自動註冊到 HTTP Router,靠的就是這一面鏡子。

但問題出在備料。

一家要快速出菜的廚房,講究的是開店前就把料備齊:該切的切好、該醃的醃上、高湯先滾著。這就是編譯器的 tree shaking,確定哪些東西這一整天用不上,就乾脆不進冰箱,省瓦斯省空間。可是一旦有了那面鏡子,沒有人敢保證客人下一秒會不會點一道需要魚骨頭熬醬汁的怪菜。來源文章說得很直白:只要編譯器證明不了某個方法永遠不會被反射存取,它就不能放心刪掉這個方法,還可能得保留類名、成員名、註解、參數等一堆 metadata。鏡子一照,什麼捨不得丟,冰箱就滿了。

所以 Dart 早在 2.0 的 Web 編譯器就不再支援 mirrors,Flutter 也一直不給用。文章裡拿 Kotlin 對比也很有味道:Kotlin 在 JVM 上什麼都照得出來,KClass.members 一應俱全;一旦換到 Kotlin/Native 編譯成本地二進位,那些「遍歷一個類結構」的能力就被官方標成 JVM only。離開了那個什麼都幫你留著的大廚房,小竈就得精打細算。

那鏡子收走之後,菜怎麼出?答案是提前把菜單寫死。現在 Dart 官方的 build_runner 文件,已經直接把 build system 當成 reflection 和 macros 的替代方案:動態發現的工作搬到編譯期或程式碼生成階段,執行時只跑已經寫明白的呼叫關係。這就像不再靠鏡子即興發揮,而是前一晚就把明天的備料清單印好,開店直接照單出菜。這和那間決定從高湯開始自己熬的廚房是同一種脾氣:基礎功夫提前做完,上菜的那一刻才穩。

對 Flutter 開發者來說,來源判斷是「基本無感,甚至可能是好事」,因為這預告了 Augmentations 要來了,一種新的擴充機制準備上桌。真正要傷腦筋的,是一些純 Dart 的伺服器、CLI 工具、測試框架和內部工具,尤其是直接 import ‘dart:mirrors’ 的專案,得像換掉一套用了多年的老食譜那樣,重新適配一次。Dart SDK 自己也正在遷移 package:test 這類套件。

一間廚房長大,總有些當年救過命的傢夥要先收進櫃子深處。鏡子退場,清單上桌,這一頓飯,從此按表操課。說不上浪漫,但爐火會更旺,出菜會更準。

想多看一點這種「提前備料」的廚房哲學,可以讀讀我們先前寫的有人把高湯先熬好了,你只負責決定今晚煮什麼,那篇聊的正是半成品與預留調味位的功夫。