SKILL.md
唯讀
名稱
dart-fix-runtime-errors
描述
使用 get_runtime_errors 與 lsp 擷取當前的 stack trace,定位出錯的程式碼行,進行修復並透過 hot_reload 驗證問題是否已解決。
解決 Dart 靜態分析錯誤
目錄
核心概念與規範
型別系統與健全性
落實 Dart 健全的型別系統(Sound Type System),防止程式在執行時期進入無效狀態。
- Method Overrides(方法覆寫): 確保回傳型別具備共變性(covariant),參數型別具備逆變性(contravariant)。除非明確加上
covariant關鍵字,否則絕不可在子類別中縮窄參數型別的範圍。 - Generics & Collections(泛型與集合): 為泛型類別明確加上型別標註(例如
List<T>、Map<K, V>)。切勿將List<dynamic>指派給指定型別的清單(例如List<Cat>)。 - Downcasting(向下轉型): 避免從
dynamic進行隱式向下轉型。必要時請使用顯式轉型(例如as List<Cat>),但必須確保執行時期的底層型別符合,以免引發TypeError例外。 - Strict Casts(嚴格轉型): 在
analysis_options.yaml的analyzer: language:設定下啟用strict-casts: true,強制要求顯式轉型,並在編譯時期即時攔截隱式向下轉型錯誤。
空值安全性
透過正確管理變數的初始化與可空性(Nullability),徹底消除與空值安全性(Null Safety)相關的靜態錯誤。
- Modifiers(修飾詞): 使用
?表示可空型別,使用!進行非空斷言,對不可為 null 的具名參數加上required。 - Late Initialization(延遲初始化): 對於保證在存取前會完成初始化的非空變數,使用
late關鍵字。這特別適用於 Dart 控制流分析無法明確證明其已初始化的頂層變數或實例變數。 - Wildcards(萬用字元): 對於不需要繫結的區域變數或參數,使用
_萬用字元(Dart 3.7+),避免觸發未被使用的變數警告。
錯誤處理
區分可復原的例外(Exceptions)與不可復原的錯誤(Errors)。
- Catching(擷取): 只針對可復原的失敗擷取
Exception的子型別。 - Errors(錯誤): 絕不要主動擷取
Error或其子型別(例如TypeError、ArgumentError)。Error代表程式設計上的 Bug,應直接修正程式碼而非捕捉例外。請啟用avoid_catching_errorslinter 規則來強制貫徹此標準。 - Rethrowing(重新拋出): 在
catch區塊中使用rethrow重新傳播例外,以完整保留原始 stack trace。
工作流程
工作流程:靜態分析錯誤修復
請依序執行以下工作流程,以找出、修復並驗證 Dart 專案中的靜態分析錯誤。你可以複製此檢核表來追蹤進度。
任務進度:
- [ ] 1. 執行靜態分析器。
- [ ] 2. 套用自動修復。
- [ ] 3. 手動修復剩餘錯誤。
- [ ] 4. 驗證修復結果(回饋迴圈)。
1. 執行靜態分析器
執行 Dart 分析器,找出目標目錄或檔案中的所有靜態錯誤。
dart analyze . --fatal-infos
2. 套用自動修復
使用 dart fix 工具自動解決標準的代码檢查(linting)與分析問題。
# 預覽變更
dart fix --dry-run
# 套用變更
dart fix --apply
3. 手動修復剩餘錯誤
檢視分析器輸出的剩餘訊息,並根據錯誤類型採取相應邏輯:
- 若錯誤屬於空值安全性問題(例如 "Property cannot be accessed on a nullable receiver"):
- 確認該變數在邏輯上是否可能為 null。
- 若可能,請使用可空鏈接(
?.)或提供備用值(??)。 - 若不可能且會在其他地方完成初始化,請在宣告時加上
late修飾詞。
- 若錯誤屬於型別不符問題(例如 "The argument type 'List<dynamic>' can't be assigned..."):
- 追蹤該變數的初始化流程。
- 在實例化時明確標註泛型型別(例如使用
<int>[]替代[])。
- 若錯誤屬於無效覆寫問題(例如 "The parameter type doesn't match the overridden method"):
- 放寬參數型別以符合父類別,或
- 若領域邏輯明確需要縮窄型別,請在參數加上
covariant關鍵字。
4. 驗證修復結果(回饋迴圈)
執行驗證工具,檢視錯誤並修復。
dart analyze .
dart test
- 若
dart analyze仍回報錯誤: 返回步驟 3。 - 若
dart test因TypeError失敗: 代表加入了無效的顯式轉型(as T)或存取了尚未初始化的late變數。請定位執行時期的錯誤位置,並修復型別階層或初始化順序。
範例
範例:修復 Dynamic List 指派錯誤
輸入(未通過靜態分析):
void printInts(List<int> a) => print(a);
void main() {
final list = []; // 被推導為 List<dynamic>
list.add(1);
list.add(2);
printInts(list); // 錯誤:無法將 List<dynamic> 指派給 List<int>
}
輸出(通過靜態分析):
void printInts(List<int> a) => print(a);
void main() {
final list = <int>[]; // 明確標註型別
list.add(1);
list.add(2);
printInts(list);
}
範例:修復方法覆寫錯誤(逆變性)
輸入(未通過靜態分析):
class Animal {
void chase(Animal a) {}
}
class Cat extends Animal {
@override
void chase(Mouse a) {} // 錯誤:縮窄了參數型別
}
輸出(通過靜態分析):
class Animal {
void chase(Animal a) {}
}
class Cat extends Animal {
@override
void chase(covariant Mouse a) {} // 明確標記為 covariant
}
範例:使用 late 修飾詞修復空值安全性問題
輸入(未通過靜態分析):
class Thermometer {
String temperature; // 錯誤:不可為 null 的實例欄位必須進行初始化
void read() {
temperature = '20C';
}
}
輸出(通過靜態分析):
class Thermometer {
late String temperature; // 將初始化檢查延遲至執行時期
void read() {
temperature = '20C';
}
}






