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を使用します。これはコンパイラへの約束です。その約束を破ると、プログラムがクラッシュします。
チャレンジ
簡単遅延初期化のための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() を呼び出す
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ自分で練習してみよう: Dartオンラインコンパイラ