Menu
Coddy logo textTech

? 演算子と ! 演算子

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

Null 許容型を扱う際、Dart は値を安全に操作するための 2 つの重要な演算子を提供しています。Null 条件演算子 ?.Null アサーション演算子 ! を使用することで、null になる可能性のある値をどのように処理するかを制御できます。

?. 演算子は、null 許容値のプロパティやメソッドに安全にアクセスします。値が null の場合、クラッシュする代わりに式全体が null を返します。

String? name = 'Alice';
print(name?.length);  // 5

name = null;
print(name?.length);  // null (クラッシュしません!)

! 演算子は Dart に「この値は null ではないと確信している」と伝えます。これは Null 許容型を Null 非許容型に変換しますが、値が実際に null である場合はエラーをスローします:

String? maybeName = 'Bob';
String definite = maybeName!;  // OK - nullではないことをアサート(断言)します
print(definite.length);  // 3

String? empty = null;
// String crash = empty!;  // ランタイムエラー!値がnullでした

null値を適切に処理したい場合は、?.を使用します。値が確実に存在すると確信している場合にのみ、!を使用してください。例えば、if文でチェックした後や、ロジックによって値が保証されていることがわかっている場合などです。!を多用すると、null安全の目的が損なわれ、実行時のクラッシュにつながる可能性があります。

challenge icon

チャレンジ

簡単

?. 演算子と ! 演算子を使用して、Null 許容値を安全に扱う方法を示す商品在庫システムを構築しましょう。

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

  • product.dart: 在庫内のアイテムを表す Product クラスを定義します。一部の商品は完全な情報を持っていますが、他の商品はまだカタログ作成中です。クラスには以下を含める必要があります:
    • Null 非許容の String name - すべての商品には名前が必要です
    • Null 非許容の double price - すべての商品には価格が必要です
    • Null 許容の String? description - 一部の商品にはまだ説明がありません
    • Null 許容 de String? category - 一部の商品はまだカテゴリ分けされていません
    • nameprice を必須パラメータとして受け取るコンストラクタ
    • ?. を使用して説明の長さを返す getDescriptionLength() メソッド。説明がない場合は null を返します
    • ! を使用してカテゴリを大文字で返す getCategoryUppercase() メソッド。このメソッドはカテゴリが設定されていることを前提とします
    • 商品情報を表示する displayProduct() メソッド。説明が null の場合は "No description" を、カテゴリが null の場合は "Uncategorized" を表示します
  • main.dart: 商品クラスをインポートし、両方の演算子を実演します:
    • 名前が 'Laptop'、価格が 999.99 の商品を作成し、その説明を 'High-performance computing device' に、カテゴリを 'Electronics' に設定します
    • 名前が 'Mystery Item'、価格が 49.99 の商品を作成します(説明とカテゴリは null のままにします)
    • Laptop の場合:displayProduct() を呼び出し、getDescriptionLength() を使用して Description length: [length] を出力し、getCategoryUppercase() を使用して Category: [uppercase] を出力します
    • Mystery Item の場合:displayProduct() を呼び出し、getDescriptionLength() を使用して Description length: [length] を出力します(これは null と表示されます)

displayProduct() メソッドは以下の形式で出力する必要があります:

Product: [name] - $[price]
Description: [description or "No description"]
Category: [category or "Uncategorized"]

期待される出力:

Product: Laptop - $999.99
Description: High-performance computing device
Category: Electronics
Description length: 32
Category: ELECTRONICS
Product: Mystery Item - $49.99
Description: No description
Category: Uncategorized
Description length: null

チートシート

null安全アクセス演算子 ?. は、nullableな値のプロパティやメソッドに安全にアクセスします。値がnullの場合、エラーをスローする代わりにnullを返します:

String? name = 'Alice';
print(name?.length);  // 5

name = null;
print(name?.length);  // null (クラッシュしません!)

nullアサーション演算子 ! は、nullable型を非nullable型に変換します。値が実際にnullである場合にランタイムエラーをスローするため、値がnullでないことが確実な場合にのみ使用してください:

String? maybeName = 'Bob';
String definite = maybeName!;  // OK - nullでないことをアサートします
print(definite.length);  // 3

String? empty = null;
// String crash = empty!;  // ランタイムエラー!

適切なnull処理には ?. を使用し、値が存在することが絶対に確実な場合にのみ ! を使用してください。

自分で試してみよう

import 'product.dart';

void main() {
  // TODO: 名前が 'Laptop'、価格が 999.99 の製品を作成してください
  // 次に、その説明を 'High-performance computing device' に設定してください
  // そして、そのカテゴリを 'Electronics' に設定してください
  
  // TODO: 名前が 'Mystery Item'、価格が 49.99 の製品を作成してください
  // 説明とカテゴリは null のままにしてください
  
  // TODO: Laptop について:
  // - displayProduct() を呼び出す
  // - getDescriptionLength() を使用して "Description length: [length]" を出力する
  // - getCategoryUppercase() を使用して "Category: [uppercase]" を出力する
  
  // TODO: Mystery Item について:
  // - displayProduct() を呼び出す
  // - getDescriptionLength() を使用して "Description length: [length]" を出力する
}
quiz icon腕試し

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

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