【Flutter】Dartのlate修飾子についてと使い方のソースコードサンプル

Flutter基礎

Dart・Flutterの基礎を学び直しててlateという修飾子の使い方についても学び直したいと思い、まとめものを記事にしました。
Flutterを使用している現場や個人開発で時々出てくる概念のため把握することでより理解度高くプロジェクトが進められたり、ドキュメントがスッと入ってきたりするかなと思います。

lateの使い方を知りたい、lateって改めてどういうものだっけと思っている方に役に立てれば幸いです。

公式

Variables
Learn about variables in Dart.

概要

lateとは

公式記載は以下のとおりです。

The late modifier has two use cases:

  • Declaring a non-nullable variable that’s initialized after its declaration.
  • Lazily initializing a variable.

日本語にすると、lateとは下記の2つのケースで使用する修飾子のことになります。

  • 宣言の後に初期化される非null変数を宣言
  • 遅延初期化変数(lazily initialized)

つまり、初期化前に宣言だけしたい場合や後で宣言したい際の変数に有効な修飾子になります。

そもそも修飾子って?

修飾子とは、変数・クラス・関数などの宣言に“追加の意味”を付けるキーワードです。

つまり、“その変数/関数/クラスがどんな性質を持つか、振る舞いを補足する言葉” です。
今回のlateでは遅らせるよの振る舞いを補足しています。

Dartにおける基本的なルール

前提としてControl Flow Analysis (制御フロー解析)というDartのnull Safetyを守るための仕組みがあり、その中で下記のようなルールがあります。

  • non-nulllable型を使うときをトップレベルやインスタンスの変数で使うときに初期化しないとエラーになることがある
    • そこでlateを使って後で初期化することでエラーを解消

Often Dart’s control flow analysis can detect when a non-nullable variable is set to a non-null value before it’s used, but sometimes analysis fails. Two common cases are top-level variables and instance variables: Dart often can’t determine whether they’re set, so it doesn’t try.

ソースコードサンプル

実際にソースコードがある方がイメージしやすいと思うので、2つのケースについて見ていきたいと思います。

  • 宣言の後に初期化される非null変数を宣言
  • 遅延初期化変数(lazily initialized)

初期化前の定義

  • 値なしで定義する
    • 後で必ず定義
late String description;

void main() {
  description = 'Feijoada!';
  print(description);
}

こうすることで

String description = 'Feijoada!';

のようにlateを使って宣言することで、定義の際に値をセットしなくても定義が可能になります。

有効なシーン

こちらは、「今この場では値は決められないが、後から必ず値をセットする」というシーンで有効になります。

例えば、「ログイン後に取得した token を保存する」下記のようなシーンで有効です。

class UserSession {
  late String token; // 必ずセットされるが取得タイミングが後
}

void login() {
  session.token = fetchToken();
}

また「DI(依存性注入)で後から差し込み可能にしたい」ケースなどにも有効です。

late Api api;

setUp(() {
  api = MockApi(); // テストごとに差し替える
});

2つとも今は必要ないが後々値のセットが必要なシーンでlateが有効活用できると思います。

遅延初期化(Lazily initialized)

  • 変数を使うときに初めて初期化する
    • 通常宣言時に初期化するが
// readThermometer()の呼び出し
late String temperature = readThermometer(); // Lazily initialized.

有効なシーン

こちらでは、「その変数を初めて使う瞬間まで初期化を遅らせたい」ケースで有効だと思います。

例えば、「重い処理があって必要になるまで実行したくない」ケースです。

// 例:時間のかかるデータ読み込み
late final data = loadBigData(); // 実際にアクセスされるまで実行されない

起動時に毎度読んでいると重たくなるので、lateを使いパフォーマンスが良くなることがわかります。

また、「ユーザーがその機能を開かなければロードしたくない」ようなケースにも有効です。
例えば、設定画面を開いたときにだけ読み込むマスターデータのような変数にはlateが有効になります。

最後に

簡単ではありますが、ここまでlateについて解説していきました。もっと細かくfinal lateの使い方や別の具体ケースなども追って更新したいと思っています。

より皆さんがFlutter開発を楽しめるような記事をこれからも書ければと思いますので他の記事もご覧いただけると幸いです。

ではまた。

コメント

タイトルとURLをコピーしました