無効な_case_パターン
Dart 3.0で有効なcase式を使用してください。
このルールは現在実験的であり、Dart 3.0以降で使用可能です。
このルールには、クイックフィックスが用意されています。
詳細
#Dart 2.19以前で有効なcase式の中には、ライブラリが3.0にアップグレードされるとエラーになるか、セマンティクスが変更されるものがあります。 このリントは、Dart 3.0への移行を容易にするために、これらの式にフラグを立てます。
2.19で有効なswitch caseの中には、Dart 3.0ではコンパイルエラーになるものがあります
- セットリテラル
- 括弧で囲まれた式
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の中には、構文的には有効なパターンであるが、パターンマッチングの動作が現在の定数等価性動作と異なる場合があります。 それらは以下のとおりです。
リストリテラルとマップリテラル。 リストまたはマップリテラルは、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".
}
パターンを使用すると、リストまたはマップリテラルはリストまたはマップパターンになります。 パターンは入力オブジェクトを分解し、サブパターンがすべて一致する場合に一致します。 つまり、リストとマップのパターンは、深い等価性のようなものを使用して一致します。
Dart 3.0では、上記のプログラムは「Matched」を2回出力します。
定数コンストラクタ呼び出し。 コレクションと同様に、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`ゲッターを呼び出して、それらの結果を対応するサブパターンと照合します。
この例では、「Matched」が2回出力されます。
オブジェクトパターンは名前付きフィールドのみをサポートすることに注意してください。 したがって、現在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」が2回出力されます。
ワイルドカード。 現在、`_`という名前の定数を使用できます
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」が2回出力されます。
論理演算子。 論理演算子`&&`と `||` は有効な定数式であり、有効なパターンでもあります。 定数式として、それらは式をブール値に評価し、入力値がそのブール値と等しい場合に一致します。 したがって、
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では、これらはパターンになります。 上記の例では、ブール値はtrueとfalseの両方になることができないため、「Did not match」が2回出力されます。
無効なcaseの多くは、現在のDartとDart 3.0の両方で有効であり、同じ意味を持つように機械的に変更できます。
括弧で囲まれた式:内部式がDart 3.0で壊れていないものである場合、括弧を破棄するだけです。
リストリテラル、マップリテラル、セットリテラル、および定数コンストラクタ呼び出し:リテラルまたは呼び出しの前に `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.5.3を反映しています。 ページの最終更新日:2024-07-03. ソースを表示 または 問題を報告する.