invalid_case_patterns
使用在 Dart 3.0 中有效的 case 表達式。
詳細資訊
#某些在 Dart 2.19 及更早版本中有效的 case 表達式,當程式庫升級至 3.0 時,將會變成錯誤或語意有所變更。此 Lint 標記這些表達式,以方便遷移至 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 在語法上也是有效的模式,但模式匹配行為可能與目前的常數相等行為不同。它們是
List 和 Map 字面值。 List 或 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".
}
使用模式時,List 或 Map 字面值會變成 List 或 Map 模式。該模式解構傳入的物件,並在所有子模式都匹配時匹配。換句話說,List 和 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 中沒有損壞的表達式,只需捨棄括號即可。
List 字面值、Map 字面值、Set 字面值和常數建構子呼叫: 在字面值或呼叫之前放置 const
。這會將其變成常數模式,從而保留目前的行為
BAD
case [1, 2]:
case {'k': 'v'}:
case {1, 2}:
case Point(1, 2):
GOOD
case const [1, 2]:
case const {'k': 'v'}:
case const {1, 2}:
case const Point(1, 2):
萬用字元: 將常數從
_
重新命名為其他名稱。由於名稱是私有的,因此可以在程式庫中本地完成,而不會影響其他程式碼。其他所有內容: 對於任何其他無效的表達式,您必須將表達式提升到新的具名常數中。例如,如果您有像這樣的程式碼
BAD
switch (n) {
case 1 + 2: ...
}
可以透過將其變更為以下內容來修正
GOOD
const three = 1 + 2;
switch (n) {
case three: ...
}
啟用
#若要啟用 invalid_case_patterns
規則,請在您的 analysis_options.yaml
檔案中的 linter > rules 下新增 invalid_case_patterns
linter:
rules:
- invalid_case_patterns
如果您改用 YAML 映射語法來配置 linter 規則,請在 linter > rules 下新增 invalid_case_patterns: true
linter:
rules:
invalid_case_patterns: true
除非另有說明,否則本網站上的文件反映的是 Dart 3.7.1 版本。頁面上次更新於 2025-03-07。 檢視原始碼 或 回報問題。