💬

[Dart/Flutter] ValueGetter<T>の仕様調査

2025/02/19に公開

ValueGetterの中身

https://api.flutter.dev/flutter/foundation/ValueGetter.html

Flutterドキュメントにも記載されているが中身は T Fuction()、つまりTを返す関数。

ただ、クラス作成時に String を仮引数にした場合と String Fuction()を仮引数にした場合 との違いがよくわからなかったので調査する。
サンプルコードを gpt にて作成

String を引数で渡した際のサンプルコード


class UserProfile {
  final String avatarBase64;

  UserProfile(this.avatarBase64); // ここでファイル読み込みが走る

  static String loadAvatar() {
    print("📷 Loading avatar...");
    return "base64data"; // 実際は画像をバイナリで取得
  }
}

void main() {
  UserProfile profile = UserProfile(UserProfile.loadAvatar());
  print("✅ Profile created!");
  print(profile.avatarBase64);
}

出力結果

📷 Loading avatar...
✅ Profile created!
base64data

loadAvatarメソッドがインスタンス化される直前に実行されていることが分かる。

String Fuction()のサンプルコード

class UserProfile {
  final String Function() avatarBase64;

  UserProfile(this.avatarBase64); // ここではまだ画像をロードしない

  static String loadAvatar() {
    print("📷 Loading avatar...");
    return "base64data"; // 実際は画像をバイナリで取得
  }
}

void main() {
  UserProfile profile = UserProfile(() => UserProfile.loadAvatar());
  print("✅ Profile created!");
  print("${profile.avatarBase64()}"); // ここで初めてロード
}

出力結果

✅ Profile created!
📷 Loading avatar...
base64data

インスタンス化してからavatarBase64()を呼ぶことで、インスタンス時に指定したloadAvatarメソッドが実行されていることが分かる。

ValueGetter<String>を使った場合のサンプルコード
class UserProfile {
  final ValueGetter<String> avatarBase64;

  UserProfile(this.avatarBase64); // ここではまだ読み込まない

  static String loadAvatar() {
    print("📷 Loading avatar...");
    return "base64data"; // 実際は画像をバイナリで取得
  }
}

void main() {
  UserProfile profile = UserProfile(() => UserProfile.loadAvatar());
  print("✅ Profile created!");
  print("📷 Avatar: ${profile.avatarBase64()}"); // ここで初めてロード
}

T Funciton()を引数に取った場合
class UserProfile<T> {
  final T Function() data;

  UserProfile(this.data); // ここではまだデータをロードしない

  static String loadAvatar() {
    print("📷 Loading avatar...");
    return "base64data"; // 実際は画像をバイナリで取得
  }
}

void main() {
  UserProfile<String> profile = UserProfile(() => UserProfile.loadAvatar());
  print("✅ Profile created!");
  print("📷 Avatar: ${profile.data()}"); // ここで初めてロード
}

まとめ

  • クラス作成時に String を仮引数にした場合
  • インスタンス化した時点で値の中身は決まっていないといけないから、インスタンス化時に実引数にした関数が実行される。
  • クラス作成時に String Fuction()を仮引数にした場合
    • インスタンス化した時点では実引数に指定した関数が実行されない。

上記の点を踏まえて、インスタンス化が何度も実行されて、かつ重い処理は String Fuction() を仮引数にした方が良さそう。

Discussion