invalid_case_patterns
使用在 Dart 3.0 中有效的 case 表達式。
此規則目前為實驗性,並於 Dart 3.0 開始提供。
此規則提供快速修正。
詳細資訊
#在 Dart 2.19 及更早版本中有效的某些 case 表達式,當函式庫升級到 3.0 時會變成錯誤或語意已變更。此程式碼檢查器會標記這些表達式,以便簡化遷移到 Dart 3.0 的過程。
2.19 中一些有效的 switch case 在 Dart 3.0 中會變成編譯錯誤
- Set 字面值
- 括號表達式
- 對
identical()
的呼叫。 - 一元運算子表達式
!
、-
或~
(除了整數文字之前的-
,這是一個有效的模式,沒有問題) - 二元運算子表達式
!=
、==
、&
、|
、^
、~/
、>>
、>>>
、<<
、+
、-
、*
、/
、%
、<
、<=
、>
、>=
、??
。 - 條件運算子
?:
- 字串上的
.length
呼叫 is
和is!
表達式
所有這些的範例
switch (obj) {
case {1}: // Set literal.
case (1): // Parenthesized expression.
case identical(1, 2): // `identical()` call.
case -pi: // Unary operator.
case 1 + 2: // Binary operator.
case true ? 1 : 2: // Conditional operator.
case 'hi'.length: // .length call.
case i is int: // is expression.
}
2.19 中一些有效的 switch case 在語法上也是有效的模式,但模式比對行為可能與目前的常數相等行為不同。它們是
清單和 Map 字面值。 清單或 Map 字面值可以作為 case 中的常數出現
switch (obj) {
case [1, 2]: ...
case {'k': 'v'}: ...
}
目前,只有當傳入值與常數具有相同的識別時,case 才會比對。所以
test(List<int> list) {
switch (list) {
case [1, 2]: print('Matched'); break;
default: print('Did not match'); break;
}
}
main() {
test(const [1, 2]); // Prints "Matched".
test([1, 2]); // Prints "Did not match".
}
使用模式,清單或 Map 字面值會變成清單或 Map 模式。該模式會解構傳入的物件,並在子模式全部比對時進行比對。換句話說,清單和 Map 模式會使用更像深層相等的方式進行比對。
在 Dart 3.0 中,以上程式碼會印出「Matched」兩次。
常數建構子呼叫。 與集合類似,您可以在 case 中建構類別的常數實例
class Point {
final int x;
final int y;
const Point({this.x, this.y});
}
test(Point p) {
switch (p) {
case Point(x: 1, y: 2): print('Matched'); break;
default: print('Did not match'); break;
}
}
main() {
test(const Point(1, 2)); // Prints "Matched".
test(Point(1, 2)); // Prints "Did not match".
}
同樣,與集合類似,只有當傳入值具有相同的識別時,case 目前才會比對。使用模式,Point(...)
語法會變成一個物件模式,它會解構傳入的點,在其上呼叫 x
和 y
getter,然後將這些結果與對應的子模式進行比對。
在此範例中,它會印出「Matched」兩次。
請注意,物件模式僅支援具名欄位。因此,今天 case 中任何帶有位置引數的常數建構子,在剖析為模式時都會變成編譯時間錯誤。不帶引數的常數建構子呼叫是有效的物件模式,僅執行類型測試
class Thing {
const Thing();
}
test(Thing t) {
switch (t) {
case Thing(): print('Matched'); break;
default: print('Did not match'); break;
}
}
main() {
test(const Thing()); // Prints "Matched".
test(Thing()); // Prints "Did not match".
}
當解譯為模式時,這會印出「Matched」兩次。
萬用字元。 今天,您可以有一個名為 _
的常數
test(int n) {
const _ = 3;
switch (n) {
case _: print('Matched'); break;
default: print('Did not match'); break;
}
}
main() {
test(3); // Prints "Matched".
test(5); // Prints "Did not match".
}
使用模式,識別符號 _
會被視為符合所有值的模式,因此這會印出「Matched」兩次。
邏輯運算子。 邏輯運算子 &&
和 ||
是有效的常數表達式,也是有效的模式。作為常數表達式,它們只會將表達式評估為布林值,並在傳入值等於該布林值時進行比對。所以
test(bool b) {
switch (b) {
case true && false: print('Matched'); break;
default: print('Did not match'); break;
}
}
main() {
test(false); // Prints "Matched".
test(true); // Prints "Did not match".
}
在 Dart 3.0 中,這些會變成模式。上面的範例印出「Did not match」兩次,因為沒有布林值可以同時為 true 和 false。
許多無效的 case 可以機械式地變更為在今天的 Dart 中有效,並且在 Dart 3.0 中有效且具有相同含意的內容。
括號表達式: 如果內部表達式在 Dart 3.0 中沒有被破壞,只需捨棄括號即可。
清單字面值、Map 字面值、Set 字面值和常數建構子呼叫: 在文字或呼叫之前放置 const
。這會將其變成常數模式,從而保留目前的行為
錯誤
case [1, 2]:
case {'k': 'v'}:
case {1, 2}:
case Point(1, 2):
正確
case const [1, 2]:
case const {'k': 'v'}:
case const {1, 2}:
case const Point(1, 2):
萬用字元: 將常數從
_
重新命名為其他名稱。由於該名稱是私有的,因此可以在函式庫中本地執行此操作,而不會影響其他程式碼。其他所有項目: 對於任何其他無效的表達式,您必須將該表達式提升到一個新的具名常數中。例如,如果您有像這樣的程式碼
錯誤
switch (n) {
case 1 + 2: ...
}
可以透過將其變更為
正確
const three = 1 + 2;
switch (n) {
case three: ...
}
用法
#若要啟用 invalid_case_patterns
規則,請在您的 analysis_options.yaml
檔案中的 linter > rules 下新增 invalid_case_patterns
linter:
rules:
- invalid_case_patterns
除非另有說明,否則本網站上的文件反映的是 Dart 3.6.0。頁面上次更新時間為 2024-07-03。 檢視原始碼 或 回報問題。