Null-Aware 演算子
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 27/110。
?. や ! に加えて、DartはNull許容型の値をより簡潔に扱うための追加の演算子を提供しています。これらの null-aware演算子 は、nullになる可能性がある値を扱う際に、よりクリーンなコードを書くのに役立ちます。
null合体演算子 ?? は、左側の値がnullでない場合はその値を返し、そうでない場合は右側の値を返します:
String? nickname;
String displayName = nickname ?? 'Guest';
print(displayName); // Guest
nickname = 'Alex';
displayName = nickname ?? 'Guest';
print(displayName); // Alexnull合体代入演算子 ??= は、変数が現在 null の場合にのみ値を代入します。
String? username;
username ??= 'Anonymous';
print(username); // Anonymous
username ??= 'NewName';
print(username); // Still Anonymous (nullではなかったため)null-aware access operator ?. を連鎖させて、ネストされたプロパティに使用できます:
String? city = user?.address?.city; // user または address が null であっても安全ですこれらの演算子はうまく組み合わせて使うことができます。例えば、Null許容(nullable)なプロパティにアクセスし、デフォルト値を提供する場合などです。
String greeting = user?.name ?? 'Stranger';
// user が null、または user.name が null の場合、'Stranger' を使用しますこれらの演算子を使用することで、プログラム全体でNull安全性を維持しながら、コードの可読性を保つことができます。
チャレンジ
簡単オプション情報を扱う際に、null-aware演算子(null許容演算子)を使用することで、コードをいかに簡潔にできるかを示すゲスト登録システムを構築しましょう。
コードは2つのファイルに分けて構成します:
guest.dart: イベントの参加者を表すGuestクラスを定義します。詳細な情報を提供するゲストもいれば、基本情報のみを提供するゲストもいます。クラスには以下の要素を含めてください:- 非null型の
String name- すべてのゲストは名前を持つ必要があります - null許容型の
String? email- すべての人がメールアドレスを提供するわけではありません - null許容型の
String? dietaryPreference- 食事の要望を指定しないゲストもいます nameを必須パラメータとして受け取るコンストラクタ??演算子を使用して、メールアドレスがあればそれを返し、なければ'No email provided'を返すgetDisplayEmail()メソッド??=演算子を使用して、dietaryPreferenceが現在 null の場合にのみ'Standard'を設定するassignDefaultDiet()メソッド?.を使用してメールアドレスの長さを返し、メールアドレスが存在しない場合はnullを返すgetEmailDomain()メソッド- ゲストのバッジ情報を表示する
printBadge()メソッド
- 非null型の
main.dart: ゲストクラスをインポートし、情報の提供レベルが異なる3人のゲストを登録します:- 名前が
'Alice'のゲストを作成し、メールアドレスを'alice@company.com'に、食事の要望を'Vegetarian'に設定します - 名前が
'Bob'のゲストを作成し、メールアドレスのみを'bob@email.org'に設定します(食事の要望は null のままにします) - 名前が
'Charlie'のゲストを作成します(メールアドレスと食事の要望は両方とも null のままにします) - 3人全員に対して
assignDefaultDiet()を呼び出します - 各ゲストの順に
printBadge()を呼び出し、次にgetEmailDomain()を使用してEmail length: [result]と出力します
- 名前が
printBadge() メソッドは以下の形式で出力する必要があります:
=== Guest Badge ===
Name: [name]
Email: [getDisplayEmail()]
Diet: [dietaryPreference or "Not specified"]??= は値が null の場合にのみ代入を行うため、Alice の食事の要望は 'Vegetarian' のままであり、Bob と Charlie にはデフォルトの 'Standard' が割り当てられることに注目してください。
期待される出力:
=== Guest Badge ===
Name: Alice
Email: alice@company.com
Diet: Vegetarian
Email length: 17
=== Guest Badge ===
Name: Bob
Email: bob@email.org
Diet: Standard
Email length: 13
=== Guest Badge ===
Name: Charlie
Email: No email provided
Diet: Standard
Email length: nullチートシート
Dartは、null許容(nullable)な値をより簡潔に扱うためのnull対応演算子(null-aware operators)を提供しています。
null合体演算子 ?? は、左側の値がnullでない場合はその値を返し、nullの場合は右側の値を返します:
String? nickname;
String displayName = nickname ?? 'Guest';
print(displayName); // Guest
nickname = 'Alex';
displayName = nickname ?? 'Guest';
print(displayName); // Alexnull対応代入演算子 ??= は、変数が現在nullである場合にのみ値を代入します:
String? username;
username ??= 'Anonymous';
print(username); // Anonymous
username ??= 'NewName';
print(username); // Still Anonymous (wasn't null) // まだAnonymous(nullではなかったため)ネストされたプロパティに対して、null対応アクセス演算子 ?. を連鎖させることができます:
String? city = user?.address?.city; // Safe even if user or address is null // userまたはaddressがnullであっても安全これらの演算子は組み合わせて使用できます:
String greeting = user?.name ?? 'Stranger';
// If user is null OR user.name is null, use 'Stranger'
// userがnull、またはuser.nameがnullの場合、'Stranger'を使用自分で試してみよう
import 'guest.dart';
void main() {
// TODO: 'Alice' という名前のゲストを作成する
// 彼女のメールアドレスを 'alice@company.com' に設定する
// 彼女の食事の好みを 'Vegetarian' に設定する
// TODO: 'Bob' という名前のゲストを作成する
// 彼のメールアドレスのみを 'bob@email.org' に設定する
// 食事の好みは null のままにする
// TODO: 'Charlie' という名前のゲストを作成する
// メールアドレスと食事の好みの両方を null のままにする
// TODO: 3人すべてのゲストに対して assignDefaultDiet() を呼び出す
// TODO: 各ゲスト(Alice、Bob、Charlie)に対して順番に:
// - printBadge() を呼び出す
// - getEmailDomain() を使用して 'Email length: [result]' を出力する
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ