📘

【Dart】コンストラクタを利用したconstインスタンスの作成失敗・成功例

2020/12/08に公開

【Dart】Constant constructor利用時に、インスタンスをconst値とする際の注意点

  • 【参考】公式のConstructors学習サイト

    • Language tour | Dart > Constructors
      • Constant constructors
        • クラスが変更されないオブジェクトを生成する場合(immutableなクラス)は、オブジェクトをコンパイル時に定数化(const)することができる。
        • これを行うには、Constant constructorでインスタンス化する。
        • クラスが持つ、すべてのインスタンス変数はfinalである必要がある。
  • 【参考】オブジェクトが同一かを比較する関数

  • 利用するサンプルクラス

    • 匿名ユーザを専用に作成するAnonymousUserクラス
class AnonymousUser {
  final String username;

  const AnonymousUser({this.username});
}

変数1つを利用した例

失敗例

  • final anonymousUser = AnonymousUser(username: 'AnonymousUser');の場合は、const値とならない
  • 判断方法は以下にて、直接constが付いたオブジェクトと比較
    • identical(anonymousUser, const AnonymousUser(username: 'AnonymousUser'))
import 'dart:core';

class AnonymousUser {
  final String username;

  const AnonymousUser({this.username});
}

void main() {
  final anonymousUser = AnonymousUser(username: 'AnonymousUser');
  print(anonymousUser.username);
  print(
      identical(anonymousUser, const AnonymousUser(username: 'AnonymousUser')));
}

実行結果

AnonymousUser
false

成功例

  • final anonymousUser = const AnonymousUser(username: 'AnonymousUser');の場合はconst値となる
import 'dart:core';

class AnonymousUser {
  final String username;

  const AnonymousUser({this.username});
}

void main() {
  final anonymousUser = const AnonymousUser(username: 'AnonymousUser');
  print(anonymousUser.username);
  print(
      identical(anonymousUser, const AnonymousUser(username: 'AnonymousUser')));
}

実行結果

AnonymousUser
true

【備考】

  • 念のため、hashCodeで同一性を確認(メモリ上のアドレスも同一か)
    • 結果は、finalのものは各自違う値となり、constのものは全て同一
class AnonymousUser {
  final String username;

  const AnonymousUser({this.username});
}

void main() {
  final anonymousUser1 = AnonymousUser(username: 'AnonymousUser');
  print(anonymousUser1.hashCode);
  final anonymousUser2 = AnonymousUser(username: 'AnonymousUser');
  print(anonymousUser2.hashCode);
  const anonymousUser3 = AnonymousUser(username: 'AnonymousUser');
  print(anonymousUser3.hashCode);
  const anonymousUser4 = AnonymousUser(username: 'AnonymousUser');
  print(anonymousUser4.hashCode);
  print(const AnonymousUser(username: 'AnonymousUser').hashCode);
}

実行結果

105736162
919716837
1012789016
1012789016
1012789016

Listを利用した例

失敗例

  • final List<AnonymousUser> anonymousUsersの場合は、const値とならない
import 'dart:core';

class AnonymousUser {
  final String username;

  const AnonymousUser({this.username});
}

void main() {
  final List<AnonymousUser> anonymousUsers = [
    AnonymousUser(username: 'AnonymousUser'),
    AnonymousUser(username: 'AnonymousUser')
  ];
  anonymousUsers.forEach(
    (AnonymousUser anonymousUser) {
      print(anonymousUser.username);
      print(identical(
          anonymousUser, const AnonymousUser(username: 'AnonymousUser')));
    },
  );
}

実行結果

AnonymousUser
false
AnonymousUser
false

成功例

  • const List<AnonymousUser> anonymousUsersの場合はconst値となる
import 'dart:core';

class AnonymousUser {
  final String username;

  const AnonymousUser({this.username});
}

void main() {
  const List<AnonymousUser> anonymousUsers = [
    AnonymousUser(username: 'AnonymousUser'),
    AnonymousUser(username: 'AnonymousUser')
  ];
  anonymousUsers.forEach(
    (AnonymousUser anonymousUser) {
      print(anonymousUser.username);
      print(identical(
          anonymousUser, const AnonymousUser(username: 'AnonymousUser')));
    },
  );
}

実行結果

AnonymousUser
true
AnonymousUser
true

Discussion