在 dart 中使用 equatable

简介: 在 dart 中使用 equatable

为什么要用 equatable

在 dart 中如果要判断一个对象的是否相等需要复写 operator ==hashCode 。总是这样的代码很无趣也没有效率。比如 要判断 两个 Person 对象是否相等,需要这样写

class Person {
  const Person(this.name);
  final String name;
  @override
  bool operator ==(Object other) =>
    identical(this, other) ||
    other is Person &&
    runtimeType == other.runtimeType &&
    name == other.name;
  @override
  int get hashCode => name.hashCode;
}
复制代码

identical(this, other) 判断这两个对象是否为同一个,如果同一个,那当然相等了。

other is Person 
    && runtimeType == other.runtimeType 
    && name == other.name;
复制代码

这三个必须同时成立才能判断相等。

  1. 确保是 person 对象
  2. 即便是 person 对象,但可能是 person 的某个子类,所以还得进一步判断 runtimeType
  3. 最后还得判断所有属性相等。

还好我们有 equatable 帮我完成 operator ==hashCode复写的工作。只需要我们给出需要判断的属性即可。

使用 equatable

第一步先安装

flutter pub add equatable
复制代码

然后引用

import 'package:equatable/equatable.dart';
复制代码

使用的时候可以直接继承,也可以用 mixin 的方式

class Person extends Equatable {
  const Person(this.name, this.favorite);
  final String name;
  final List<String> favorite;
  @override
  List<Object?> get props => [name, favorite];
}
复制代码

class Person with EquatableMixin {
  const Person(this.name, this.favorite);
  final String name;
  final List<String> favorite;
  @override
  List<Object?> get props => [name, favorite];
}
复制代码

注意事项

参与检测的属性都必须是 final

如果参与检测的属性是可变的,那么 计算出的 hascode 也是可以变的,再用 hascode 判断相等就不可靠了。有的时候 final 也防止不了改变,这个时候就靠自己避免了。

比如 在 Person 类中 favorite 是一个 list,虽然  list 本身不能修改,但是 list 的内容是可以修改的。

可以把 favorite  私有化,避免外部修改,这样只要保证 person 内部不修改 favorite 就可以了。

class Person with EquatableMixin {
  const Person(this.name, List<String> favorite):_favorite=favorite;
  final String name;
  final List<String> _favorite;
  @override
  List<Object?> get props => [name, _favorite];
}
复制代码

判断相等,不需要判断参数为 null

因为 null 除了和自己相等,不和任何其它变量相等。判断 null 显得多此一举。

如果自己 重载 operator ==, 不要这样写

class Person {
  final String name;
  // ···
  bool operator ==(Object? other) =>
      other != null && other is Person && name == other.name;
}
复制代码

要这样写

class Person {
  final String name;
  // ···
  bool operator ==(Object other) => other is Person && name == other.name;
}
复制代码

toString

最后还有一个小福利。equatable 还 override toString 方法,通过 override stringify 来控制如何显示 toString  的内容。

@override
  bool? get stringify => true;
复制代码

stringify 是 equatable 属性,默认是 null,如果我们修改为 true,在调用 toString 的时候,会显示包含 props 的更详细的信息。


目录
相关文章
|
6月前
|
Dart 编译器 API
Dart笔记:Dart 库
Dart笔记:Dart 库
164 0
|
JSON Dart 编译器
Dart简单介绍
Dart是一种面向对象、用于构建高性能应用程序的编程语言,它具有快速开发、易于维护和可移植性等特点,因此在 Flutter 应用程序开发方面越来越受欢迎。在这篇文章中,我们将深入探讨 Dart 语言的一些技术思考。 类型系统
Dart简单介绍
|
Dart JavaScript 前端开发
Flutter与一些常用的Dart语法
Flutter与一些常用的Dart语法
Flutter与一些常用的Dart语法
|
Dart JavaScript 前端开发
Numbers——Dart
Dart中的数字类型有两种,int和double。
Runes——Dart
Dart中,Runes是指UTF-32定义的Unicode字符串。 Unicode使用数字表示世界上所有的字母、数字和符号。因为Dart中的String是一系列UTF-16字节单元,而在String中想要表示32位的Unicode值,则需要特殊的语法。 一般我们使用 `\uXXXX` 这种形式表示一个Unicode码,`XXXX`表示4个十六进制值。例如,字符(♥)的Unicode字符是`\u2665`。 当十六进制数据多余或者少于4位时,将十六进制数放入到花括号中,例如,微笑表情(😆)是`\u{1f600}`。 String类中有几个属性你可以用来获取`rune`信息。
|
Dart 开发工具
使用 dart tear-off
使用 dart tear-off
133 0
|
Dart
Flutter之搞定Dart(二上)
这里,我只列出来相对其他语言比较特殊的运算符,因为某些运算符太简单了,不浪费时间,比如+、-、+=、==。 你可能会疑惑,Dart为什么要搞出这么多特殊的运算符呢? 你要坚信一点:所有这些特殊的运算符都是为了让我们在开发中可以更加方便的操作,而不是让我们的编码变得更加复杂。
165 0
Flutter之搞定Dart(二上)
|
存储 Dart
Flutter之搞定Dart(二下)
这里,我只列出来相对其他语言比较特殊的运算符,因为某些运算符太简单了,不浪费时间,比如+、-、+=、==。 你可能会疑惑,Dart为什么要搞出这么多特殊的运算符呢? 你要坚信一点:所有这些特殊的运算符都是为了让我们在开发中可以更加方便的操作,而不是让我们的编码变得更加复杂。
329 0
Flutter之搞定Dart(二下)
|
自然语言处理 Dart JavaScript
Flutter之搞定Dart(一)
Google为Flutter选择了Dart就已经是既定的事实,无论你多么想用你熟悉的语言,比如JavaScript、Java、Swift、C++等来开发Flutter,至少目前都是不可以的。 在讲解Dart的过程中,我会假定你已经有一定的编程语言基础,比如JavaScript、Java、Python、C++等。
390 0
Flutter之搞定Dart(一)
|
Dart 监控 索引
Flutter之搞定Dart(二中)
这里,我只列出来相对其他语言比较特殊的运算符,因为某些运算符太简单了,不浪费时间,比如+、-、+=、==。 你可能会疑惑,Dart为什么要搞出这么多特殊的运算符呢? 你要坚信一点:所有这些特殊的运算符都是为了让我们在开发中可以更加方便的操作,而不是让我们的编码变得更加复杂。
194 0