# Flutter - Freezed
# 参考資料
- freezed パッケージの使い方 (opens new window)
- immutable なクラスを扱いやすくする機能をコード生成で提供してくれる freezed を使ってみる (opens new window)
# なんのために使うか
- 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 {
('name.isNotEmpty', 'name cannot be empty')
('age >= 0')
factory Person({
String? name,
int? age,
}) = _Person;
}
# デフォルト値
class Person with _$Person {
factory Person({
("") String? name,
(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);
}