Menu
Coddy logo textTech

Late変数

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

lateキーワードは、非ヌル許容(non-nullable)変数が、すぐには代入されなくても、使用される前に初期化されることをDartに伝えます。これは、宣言時やコンストラクタでフィールドを初期化できないものの、アクセスされる前に必ず値を持つことが確実な場合に便利です。

class User {
  late String username;
  
  void initialize(String name) {
    username = name;
  }
  
  void greet() {
    print('Hello, $username!');
  }
}

User user = User();
user.initialize('Alice');
user.greet();  // Hello, Alice!

late がないと、Dart は username が初期化されていないと警告します。late 修飾子は、読み取る前に値を代入することを約束するものです。

late のもう一つの利点は、遅延初期化です。初期化子を持つ late 変数は、最初にアクセスされるまでその値を計算しません:

class Config {
  late String settings = loadSettings();
  
  String loadSettings() {
    print('Loading...');
    return 'default';
  }
}

Config config = Config();
print('Config created');
print(config.settings);  // ここで "Loading..." が出力され、その後に "default" が出力されます

loadSettings() メソッドは、オブジェクトが作成されたときではなく、settings が最初にアクセスされたときにのみ実行されます。ただし、初期化される前に late 変数にアクセスすると、実行時エラーが発生するので注意してください。

challenge icon

チャレンジ

簡単

late 変数を使用して、遅延初期化(deferred initialization)と遅延評価(lazy initialization)の両方を実演するデータベース接続マネージャーを作成しましょう。

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

  • database.dart: データベース接続をシミュレートする Database クラスを定義します。クラスには以下の要素を含めてください:
    • オブジェクト作成後に設定される late String connectionString
    • Checking connection... と出力し、'Connected' を返す遅延初期化子を持つ late String status
    • connectionString を設定し、Connection configured: [connectionString] と出力する connect(String connStr) メソッド
    • Executing on [connectionString]: [sql] と出力する query(String sql) メソッド
    • Status: [status] と出力する checkStatus() メソッド(これにより、最初の呼び出し時に遅延評価がトリガーされます)
  • main.dart: データベースクラスをインポートし、late の両方の使い方を実演します:
    • Database インスタンスを作成する
    • Database object created と出力する
    • 接続文字列 'localhost:5432/mydb' を指定して connect() を呼び出す
    • 'SELECT * FROM users' を指定して query() を呼び出す
    • checkStatus() を呼び出して遅延評価をトリガーする

connectionString がオブジェクト作成後に手動で設定される一方で、status は最初にアクセスされたときにのみ値を計算することに注目してください。

期待される出力:

Database object created
Connection configured: localhost:5432/mydb
Executing on localhost:5432/mydb: SELECT * FROM users
Checking connection...
Status: Connected

チートシート

late キーワードを使用すると、使用される前に後で初期化される非 null 許容変数を宣言できます。

class User {
  late String username;
  
  void initialize(String name) {
    username = name;
  }
}

User user = User();
user.initialize('Alice');

遅延初期化: 初期化子を持つ late 変数は、最初にアクセスされたときにのみその値を計算します。

class Config {
  late String settings = loadSettings();
  
  String loadSettings() {
    print('Loading...');
    return 'default';
  }
}

Config config = Config();  // loadSettings() はまだ呼び出されていません
print(config.settings);     // ここで loadSettings() が呼び出されます

警告: 初期化前に late 変数にアクセスすると、実行時エラーが発生します。

自分で試してみよう

import 'database.dart';

void main() {
  // TODO: Database インスタンスを作成する
  
  // TODO: 'Database object created' と出力する
  
  // TODO: 'localhost:5432/mydb' を引数に指定して connect() を呼び出す
  
  // TODO: 'SELECT * FROM users' を引数に指定して query() を呼び出す
  
  // TODO: checkStatus() を呼び出して遅延初期化をトリガーする
}
quiz icon腕試し

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

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