パターンとマッチング (3.0)
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 87/110。
Dart 3では、単一の式でデータを構造分解して検査するための強力な手法であるパターンマッチングが導入されました。パターンを使用すると、オブジェクトからの値の抽出、構造のチェック、変数のバインドをすべて一度に行うことができます。
レコードによる基本的な分割代入については、すでに学習しました。パターンはこれを拡張し、オブジェクト、リスト、マップでも動作するようにします:
void main() {
// リストのパターン
var numbers = [1, 2, 3];
var [a, b, c] = numbers;
print('$a, $b, $c'); // 1, 2, 3
// マップのパターン
var user = {'name': 'Alice', 'age': 30};
var {'name': name, 'age': age} = user;
print('$name is $age'); // Alice is 30
}パターンは、switch 式において特に強力になります。型、値、構造を同時にマッチさせることができます。
String describe(Object obj) {
return switch (obj) {
int n when n < 0 => 'Negative number',
int n => 'Positive number: $n',
String s => 'String of length ${s.length}',
[int first, ...] => 'List starting with $first',
_ => 'Something else',
};
}
void main() {
print(describe(-5)); // 負の数
print(describe(42)); // 正の数: 42
print(describe([1, 2, 3])); // 1で始まるリスト
}when 句はパターンに条件を追加し、... はリスト内の残りの要素に一致します。アンダースコア _ は、あらゆるものに一致するワイルドカードとして機能します。シールドクラスと組み合わせることで、パターンは複雑なデータ構造の網羅的で型安全な処理を可能にします。
チャレンジ
簡単パターンマッチングを使用して、さまざまな種類の入力を分析および分類するデータ分類器を作成しましょう!Dart 3の強力なパターンマッチング機能を使用して、さまざまなデータ構造を識別し、説明するシステムを作成します。
コードを2つのファイルに整理します:
classifier.dart:Object型のパラメータを受け取り、String型の説明を返すclassifyという関数を作成します。パターンマッチングを備えたswitch式を使用して、以下のケースを処理します:- 空のリスト
[]はEmpty listを返す必要があります - 整数要素が1つだけのリストは
Single item: [value]を返す必要があります - 要素がちょうど2つのリストは
Pair: [first] and [second]を返す必要があります - 整数で始まり、その後にさらに要素が続くリストは
List starting with [first], length: [total length]を返す必要があります(...レストパターンを使用してください) 'name'と'age'の両方のキーを含むマップは[name] is [age] years oldを返す必要があります(マップパターンの非構造化を使用してください)- 負の整数(
when句を使用)はNegative: [value]を返す必要があります - 0である整数は
Zeroを返す必要があります - その他の整数は
Positive: [value]を返す必要があります - その他の値は
Unknown typeを返す必要があります
- 空のリスト
main.dart: 分類器をインポートし、さまざまな入力でパターンマッチングを実演します。以下の各値を分類した結果を出力してください:- 空のリスト
[] - 要素が1つのリスト:
[42] - 要素が2つのリスト:
['hello', 'world'] - より長いリスト:
[1, 2, 3, 4, 5] - マップ:
{'name': 'Alice', 'age': 25} - 整数
-10 - 整数
0 - 整数
99
- 空のリスト
このチャレンジでは、リストパターン、マップパターン、ガードのための when 句、およびレストパターン(...)を組み合わせます。これらはすべてレッスンで学んだ主要なパターンマッチング機能です!
期待される出力:
Empty list
Single item: 42
Pair: hello and world
List starting with 1, length: 5
Alice is 25 years old
Negative: -10
Zero
Positive: 99チートシート
Dart 3では、単一の式でデータのデストラクト(構造分解)と検査を行うためのパターンマッチングが導入されました。
リストパターン
リストから値を抽出します:
var numbers = [1, 2, 3];
var [a, b, c] = numbers;
print('$a, $b, $c'); // 1, 2, 3マップパターン
キーによってマップをデストラクトします:
var user = {'name': 'Alice', 'age': 30};
var {'name': name, 'age': age} = user;
print('$name is $age'); // Alice is 30パターンを使用したSwitch式
型、値、および構造に基づいてマッチングを行います:
String describe(Object obj) {
return switch (obj) {
int n when n < 0 => 'Negative number',
int n => 'Positive number: $n',
String s => 'String of length ${s.length}',
[int first, ...] => 'List starting with $first',
_ => 'Something else',
};
}パターンの機能
when句: パターンに条件を追加します...(レストパターン): リスト内の残りの要素にマッチします_(ワイルドカード): あらゆるものにマッチします
自分で試してみよう
import 'classifier.dart';
void main() {
// TODO: classify 関数を使用して各値を分類する
// そして結果をプリントする
// 空のリストでテストする
print(classify([]));
// TODO: 1つの要素を含むリストでテストする: [42]
// TODO: 2つの要素を含むリストでテストする: ['hello', 'world']
// TODO: より長いリストでテストする: [1, 2, 3, 4, 5]
// TODO: マップでテストする: {'name': 'Alice', 'age': 25}
// TODO: 整数 -10 でテストする
// TODO: 整数 0 でテストする
// TODO: 整数 99 でテストする
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ13高度な OOP の概念
コンポジション vs 継承拡張メソッドCallable クラスSealed クラス (Dart 3)レコード (Dart 3)パターンとマッチング (3.0)メソッドを持つ Enum