Menu
Coddy logo textTech

Nullable と Non-Nullable

CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 24/110。

Null安全がなぜ重要なのかを理解したところで、nullを保持できる変数を宣言する方法を見ていきましょう。Dartでは、型名の後に?を付けることで、その型をNull許容(nullable)にすることができます。

String name = 'Alice';   // 非 null 型 - 常に値を持つ必要があります
String? nickname;        // Null 許容型 - null または String のいずれかになります

print(name);      // Alice
print(nickname);  // null

主な違いは、非 null 許容型は値が存在することを保証するのに対し、null 許容型は値がないことを明示的に許容することです。この区別はすべての型に適用されます:

int count = 10;       // 値を持つ必要があります
int? optionalCount;   // nullを許容します

List<String> items = [];      // リストである必要があります(空でも可)
List<String>? maybeItems;     // nullになる可能性があります(リスト自体が存在しない)

空のリスト []null とは異なることに注意してください。空のリストは存在しますが、何も含まれていません。null はリストが全く存在しないことを意味します。

コンパイラはこれらのルールを厳格に適用します。非 null 許容型の変数に null を代入することはできません。また、最初に null チェックを行わずに、非 null 許容型が期待される場所で null 許容型の変数を使用することはできません:

String? maybeName = 'Bob';
// String definite = maybeName;  // エラー! Null 許容型を Null 非許容型に代入することはできません

次のレッスンでは、null許容値を安全に扱うためにDartが提供する演算子について学びます。

challenge icon

チャレンジ

簡単

null許容型とnull非許容型を使用して、必須情報とオプション情報の違いを示す映画ウォッチリストシステムを構築しましょう。

コードを整理するために2つのファイルを作成します:

  • movie.dart: ウォッチリスト内の映画を表す Movie クラスを定義します。すべての映画にはタイトルと公開年(これらは常に必須です)が必要ですが、一部の追加詳細はすべての映画で利用できるとは限りません。クラスには以下を含める必要があります:
    • null非許容の String title - すべての映画にタイトルが必要です
    • null非許容の int year - すべての映画に公開年が必要です
    • null許容の String? director - 監督が不明な場合があります
    • null許容の double? rating - すべての映画がまだ評価されているわけではありません
    • titleyear を必須パラメータとして受け取るコンストラクタ
    • 映画の情報を表示する displayInfo() メソッド。監督が不明な場合は "Unknown"、評価がない場合は "Not rated" と表示します
  • main.dart: 作成した映画クラスをインポートし、完全なデータと不完全なデータの両方の映画データを示す小さなウォッチリストを作成します:
    • タイトルが 'Inception'、公開年が 2010 の映画を作成し、監督を 'Christopher Nolan'、評価を 8.8 に設定します
    • タイトルが 'The Matrix'、公開年が 1999 の映画を作成し、評価のみを 8.7 に設定します(監督はnullのままにします)
    • タイトルが 'Upcoming Film'、公開年が 2025 の映画を作成します(監督と評価は両方ともnullのままにします)
    • 上記の順序で各映画の displayInfo() を呼び出します

displayInfo() メソッドは、次の正確な形式で出力する必要があります:

[title] ([year])
Director: [director or "Unknown"]
Rating: [rating or "Not rated"]

null非許容フィールド(titleyear)は常に値があることが保証されている一方で、null許容フィールド(director?rating?)は未設定のままにできることに注目してください。これは、一部のデータが不可欠で、一部がオプションであるという現実世界のシナリオを反映しています。

期待される出力:

Inception (2010)
Director: Christopher Nolan
Rating: 8.8
The Matrix (1999)
Director: Unknown
Rating: 8.7
Upcoming Film (2025)
Director: Unknown
Rating: Not rated

チートシート

Dartで型をNull許容(nullable)にするには、型名の後に ? を付けます:

String name = 'Alice';   // Non-nullable(Null非許容) - 常に値を持つ必要があります
String? nickname;        // Nullable(Null許容) - null または String になり得ます

この区別はすべての型に適用されます:

int count = 10;       // 値を持つ必要があります
int? optionalCount;   // null になり得ます

List<String> items = [];      // リストである必要があります(空でも可)
List<String>? maybeItems;     // null になり得ます(リスト自体が存在しない)

空のリスト []null は異なります。空のリストは存在しますが、何も含まれていません。一方、null はリスト自体が全く存在しないことを意味します。

コンパイラはNullセーフティのルールを厳格に適用します。Null非許容の変数に null を代入することはできません。また、Null許容の変数を、Null非許容の変数が期待される場所で、事前にNullチェックを行わずに使用することもできません:

String? maybeName = 'Bob';
// String definite = maybeName;  // エラー!Null許容型をNull非許容型に代入することはできません

自分で試してみよう

import 'movie.dart';

void main() {
  // TODO: タイトルが 'Inception'、公開年が 2010 の映画を作成してください
  // その後、監督を 'Christopher Nolan' に、評価を 8.8 に設定してください
  
  // TODO: タイトルが 'The Matrix'、公開年が 1999 の映画を作成してください
  // その後、評価のみを 8.7 に設定してください(監督は null のままにします)
  
  // TODO: タイトルが 'Upcoming Film'、公開年が 2025 の映画を作成してください
  // 監督と評価は両方とも null のままにします
  
  // TODO: 各映画に対して displayInfo() を順番に呼び出してください
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン