# Flutter - Freezed

# 参考資料

# なんのために使うか

  • Dart では多くのオブジェクトが immutable であり、多くの利点がある。
  • その反面、mutable なオブジェクトを扱うのは大変。その大変さを軽減するためのライブラリである。

# 何ができるか

  • アサーション
  • デフォルト値の設定
  • 遅延初期化
  • deprecated の指定
  • toString
  • hashCode
  • ==(すべてのプロパティが等しいか)
  • CopyWith(既存オブジェクトの一部のプロパティのみを変更して新しく作成)
  • FromJson/ToJson

# インストール

# pubspec.yaml
dependencies:
  # freezedのアノテーションを利用可能にする
  freezed_annotation:

dev_dependencies:
  # コードジェネレータのランナー
  build_runner:
  # コードジェネレータ
  freezed:

# 使い方

// main.dart

// パッケージのインポート
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

// 自動生成されるコードを読み込む
part 'main.freezed.dart';

// モデルの宣言(_$Personと_Personは後で自動生成されるクラスのこと)
class Person with _$Person {
  factory Person({
    String? name,
    int? age,
  }) = _Person;
}

// 使うとき
var person = Person(name: 'Remi', age: 24);
print(person.name); // Remi
print(person.age); // 24

コードの自動生成方法

flutter pub run build_runner build

# 機能

# アサーション

abstract class Person with _$Person {
  @Assert('name.isNotEmpty', 'name cannot be empty')
  @Assert('age >= 0')
  factory Person({
    String? name,
    int? age,
  }) = _Person;
}

# デフォルト値

class Person with _$Person {
  factory Person({
    @Default("") String? name,
    @Default(18) int? age,
  }) = _Person;
}

# deprecated


class Person with _$Person {
  const factory Person({
    String? name,
    int? age,
     Gender? gender,
  }) = _Person;
}

# toString

print(Person(name: 'Remi', age: 24)); // Person(name: Remi, age: 24)

# ==

print(
  Person(name: 'Remi', age: 24) == Person(name: 'Remi', age: 24),
); // true

# copyWith

var person = Person('Remi', 24);

// `age` not passed, its value is preserved
print(person.copyWith(name: 'Dash')); // Person(name: Dash, age: 24)

// `age` is set to `null`
print(person.copyWith(age: null)); // Person(name: Remi, age: null)

deepCopy もできる。詳細はこちら (opens new window)を参照。

# FromJson/ToJson

  • json_serializableと適合するようにできる。
  • そのためには以下の2つの追記が必要。
    • part 'model.g.dart';
    • factory Model.fromJson(Map<String, dynamic> json) => _$ModelFromJson(json);
import 'package:freezed_annotation/freezed_annotation.dart';

part 'person.freezed.dart';
part 'person.g.dart';


class Person with _$Person {
  const factory Person({
    String? name,
    int? age,
     Gender? gender,
  }) = _Person;

  factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
}