Menu
Coddy logo textTech

late キーワードと Null Safety

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

場合によっては、null 非許容変数が必要でも、その値をすぐに代入できないことがあります。lateキーワードは、Dart に「使用する前に必ず初期化します」と伝えます。

late String description;

void setup() {
  description = 'Initialized later';
}

void main() {
  setup();
  print(description);  // 動作する - 使用前に初期化されている
}

late がなければ、Dart は description が initialized されていないと警告します。late を使うことで、アクセスする前に値が設定されていることを保証する責任を負います。initialization の前に読み取ろうとすると、実行時エラーが発生します。

一般的な使用例は、実際に必要になるまで遅延させたい、コストの高い計算です。

class DataProcessor {
  late List<int> data = _loadData();
  
  List<int> _loadData() {
    print('Loading data...');
    return [1, 2, 3, 4, 5];
  }
}

DataProcessor processor = DataProcessor();
// 'Loading data...' はまだ出力されていません
print(processor.data);  // ここで読み込まれて出力されます

_loadData()メソッドは、オブジェクトがcreatedされたときではなく、dataがfirst accessedされたときにのみ実行されます。このlazy initializationにより、その値が決して必要にならない可能性がある場合のパフォーマンスを向上させられます。

変数が使用される前に初期化されると確信しているものの、宣言時には初期化できない場合は、lateを使用します。これはコンパイラへの約束です。その約束を破ると、プログラムがクラッシュします。

challenge icon

チャレンジ

簡単

遅延初期化のためのlate変数の威力を示す Configuration マネージャーを構築しましょう。設定が実際に必要になったときにだけ、コストの高いセットアップ処理が行われるシステムを作成します。

コードを2つのファイルに分けて整理します。

  • config_manager.dart:アプリケーション設定を扱うConfigManagerクラスを定義します。このクラスには次の要素を含めます。
    • コンストラクターを通じて渡されるString appName
    • セットアップメソッドによって後から初期化されるlate String databaseUrl
    • 初めてアクセスされたときにCalculating max connections...と出力し、100を返す、遅延初期化を使用したlate int maxConnections
    • databaseUrlを初期化するsetupDatabase(String url)メソッド
    • 現在の設定を出力するdisplayConfig()メソッド
  • main.dart:Config マネージャーをインポートし、late 変数の動作を示します。
    • アプリ名'MyApp'ConfigManagerを作成する
    • Config createdを出力する
    • URL'localhost:5432/mydb'を指定してsetupDatabaseを呼び出す
    • Accessing max connections...を出力する
    • maxConnectionsの値を出力する
    • Accessing max connections again...を出力する
    • もう一度maxConnectionsの値を出力する(計算メッセージが繰り返されないことに注目してください)
    • displayConfig()を呼び出す

displayConfig()メソッドは、次の形式で出力します。

--- Configuration ---
App: [appName]
Database: [databaseUrl]
Max Connections: [maxConnections]

遅延maxConnectionsの計算は1回だけ、つまり初めてアクセスしたときにのみ実行されることに注目してください。これが、初期化子とともにlateを使用するメリットです。

期待される出力:

Config created
Accessing max connections...
Calculating max connections...
100
Accessing max connections again...
100
--- Configuration ---
App: MyApp
Database: localhost:5432/mydb
Max Connections: 100

自分で試してみよう

import 'config_manager.dart';

void main() {
  // TODO: アプリ名 'MyApp' の ConfigManager を作成する
  
  // TODO: Print 'Config created'
  
  // TODO: Call setupDatabase with URL 'localhost:5432/mydb'
  
  // TODO: Print 'Accessing max connections...'
  
  // TODO: Print the value of maxConnections
  
  // TODO: Print 'Accessing max connections again...'
  
  // TODO: Print the value of maxConnections again
  // (計算メッセージが繰り返されないことに注意)
  
  // TODO: displayConfig() を呼び出す
}
quiz icon腕試し

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

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

自分で練習してみよう: Dartオンラインコンパイラ