跳至主要內容
YIM NEWS

科普

Dart 3.15 讓 this 學會了類型提升:開發者少寫一行 var self,程式語言補上一個多年的缺口

Dart 3.15 讓 this 終於支援類型提升,開發者不再需要 var self = this 這個繞路寫法,本文說明這個改動的機制與實際影響。

科技 科普
刊登:(台北時間) 閱讀約 3 分鐘
Dart 3.15 讓 this 學會了類型提升:開發者少寫一行 var self,程式語言補上一個多年的缺口 封面版畫

2026 年 10 月 20 日,掘金開發者「戀貝de小郭」發文介紹 Dart 3.15 的一項改動:this 關鍵字開始支援類型提升(type promotion)。這個改動幅度不大,卻處理了 Dart 型別系統裡一個存在多年的限制,也是許多 Dart 與 Flutter 開發者再熟悉不過的那行例行公事。

問題出在哪:編譯器知道,但不讓你用

先講機制。在物件導向語言裡,父類別方法中的 this,靜態型別是父類別,但執行時指向的物件可能是任何子類別。以來源文章的例子來說,Shape 是父類別,Circle 是子類別並且多了 radius 屬性。當你在 Shape 的方法裡寫 if (this is Circle),編譯器確實已經知道這個分支裡的物件是 Circle,但舊版 Dart 不會因此把 this 的靜態型別從 Shape 改成 Circle,接著寫 this.radius 會直接編譯錯誤,因為編譯器仍按 Shape 去查找 radius。

用日常比喻:櫃檯人員明明已經看了你的證件,確認你是會員,系統畫面上卻還是把你當一般訪客,每次要進會員區都得再刷一次證。開發者過去的解法就是先寫 var self = this,把 this 裝進一個區域變數,讓這個變數去參與型別提升。這行代碼本身沒有意義,純粹是為了安撫編譯器。

3.15 之後:判斷成立,型別跟著走

從 Dart 3.15 開始,this 可以像區域變數一樣,依 is 判斷或空值檢查自動改變靜態型別。if (this is Circle) 成立的分支裡,this 的靜態型別提升為 Circle,可以直接存取 radius,甚至不寫 this. 前綴、直接寫 radius 也行,因為編譯器會把隱式的實例成員存取,一起納入已提升的 this 型別來判斷。

另一個更貼近日常的場景是可空型別的 Extension。Dart 允許對 int? 這種可空型別加 Extension,在裡面檢查 this == null 之後提前返回,剩餘的程式碼按理說 this 已經是 int 了。舊版同樣不做這個提升,開發者還是要先定義一個 區域變數 self 來接手。現在可以直接 if (this == null) return true; 然後在後面安心使用 isEven,少一層仲介變數。

值得分清楚的一點:這個改動改變的是編譯器在各個分支裡理解的靜態型別,物件本身的實際型別從頭到尾沒變。它拿掉的是開發者與編譯器之間的翻譯成本,而不是新增了任何執行時行為。

所以呢

對既有的 Dart 與 Flutter 專案來說,這不代表要大改程式碼,舊寫法依然合法。比較實際的影響有兩個:新代碼可以少寫一堆 var self = this,這類樣板減少後,閱讀時的雜訊也少一分;而 Extension 處理可空型別的寫法變得更直觀,對封裝工具庫的人尤其有感。習慣了舊限制的開發者,升級到 3.15 之後最大的改變,可能就是那些原本「照規矩」多寫的一行,從此可以刪掉了。

主題

#dart3.15#開發工具#程式語言