☃️
freezedのオブジェクトの `==` による等価比較
dart ではこういう等価比較をした場合にオブジェクトが同じかを比較する(==
や hashCode
が override されていなければ)。
class Item {
Item({ required this.name });
final String name;
}
void main() {
final item1 = Item(name: 'a');
final item2 = Item(name: 'a');
print(item1 == item2); // falseになる
}
これが @freezed のクラスだと kotlin の data class っぽい挙動となり、異なるオブジェクト同士の ==
でも各プロパティが一致していれば、等価扱いとなる。
class FreezedItem with _$FreezedItem {
const FreezedItem._();
factory FreezedItem({
required String name,
}) = _FreezedItem;
}
void main() {
final item1 = FreezedItem(name: 'a');
final item2 = FreezedItem(name: 'a');
print(item1 == item2); // trueになる
}
これに関しては、freezedのドキュメントにも下記のように言及されており、
- a default ==/toString implementation which respectively compares/shows all properties of the object
自動生成コードを見ても下記のような実装がされているためである。
operator ==(dynamic other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _FreezedItem &&
const DeepCollectionEquality().equals(other.name, name));
}
int get hashCode =>
Object.hash(runtimeType, const DeepCollectionEquality().hash(name));
bool
こういうときにオブジェクト同士を比較したい場合は identicalメソッド で比較する。
class FreezedItem with _$FreezedItem {
const FreezedItem._();
factory FreezedItem({
required String name,
}) = _FreezedItem;
}
void main() {
final item1 = FreezedItem(name: 'a');
final item2 = FreezedItem(name: 'a');
final item3 = item2;
print(item1 == item2); // trueになる
print(identical(item1, item2)); // falseになる
print(identical(item2, item3)); // trueになる
}
Discussion