在 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 的更详细的信息。


目录
相关文章
|
9月前
|
存储 关系型数据库 MySQL
为什么MySQL索引结构是B+tree ?
在MySQL中,为了提高检索效率和稳定性,采用了B+树作为索引的数据结构。相比二叉树或B树,B+树的非叶子节点仅存储key和指针,使得每页能容纳更多key,树的层级更浅,检索更快;所有数据集中在叶子节点,形成双向链表,利于区间查询。以16KB页为例,三层B+树可容纳约2190万条数据。
205 1
|
负载均衡 持续交付 Docker
Docker的应用场景有哪些?
Docker的应用场景有哪些?
426 6
|
人工智能 前端开发 Serverless
阿里云百炼应用实践系列-AI助手快速搭建
本文主要介绍如何基于阿里云百炼平台快速在10分钟为您的网站添加一个 AI 助手。我们基于阿里云百炼平台的能力,以官方帮助文档为参考,搭建了一个以便全天候(7x24)回应客户咨询的AI助手,介绍了相关技术方案和主要代码,供开发者参考。
1816 15
阿里云百炼应用实践系列-AI助手快速搭建
|
关系型数据库 MySQL Linux
在CentOS上使用yum安装与使用MySQL
在CentOS操作系统上使用yum包管理器安装和配置MySQL数据库的详细步骤,包括下载MySQL的yum源配置、安装MySQL服务、启动和停止服务、设置开机自启动、获取临时密码、修改root用户密码、授权用户以及处理相关问题。同时,文章还包含了一些操作的截图,帮助用户更直观地理解安装和配置过程。
3395 0
在CentOS上使用yum安装与使用MySQL
|
Dart 前端开发 Java
【Flutter前端技术开发专栏】Flutter中的内存泄漏检测与解决
【4月更文挑战第30天】本文探讨了Flutter应用中的内存泄漏检测与解决方法。内存泄漏影响性能和用户体验,常见原因包括全局变量、不恰当的闭包使用等。开发者可借助`observatory`工具或`dart_inspector`插件监测内存使用。解决内存泄漏的策略包括避免长期持有的全局变量、正确管理闭包、及时清理资源、妥善处理Stream和RxDart订阅、正确 disposal 动画和控制器,以及管理原生插件资源。通过这些方法,开发者能有效防止内存泄漏,优化应用性能。
805 0
【Flutter前端技术开发专栏】Flutter中的内存泄漏检测与解决
|
缓存 移动开发 监控
Flutter 流畅度优化实践总结
“围绕 Flutter 流畅度体感优化,分享了挑战、线上线下监控工具建设、优化手段在组件容器沉淀,最后给出了优化建议。"
2018 0
Flutter 流畅度优化实践总结
|
消息中间件 Java Kafka
flink问题之在通过TableFunction实现行转列时Row一直是空如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
433 1
|
存储 Dart 编译器
Dart笔记:Dart语言中的注解(元数据)
Dart笔记:Dart语言中的注解(元数据)
679 0
|
JSON API 数据格式
如何获取虾皮shopee根据ID取商品详情 API接口
以下是一篇关于如何使用Shopee API接口根据商品ID获取商品详情的5000字文章,包括API接口的基本信息、请求方法、请求参数、返回数据等,以及使用Python进行API调用的示例代码。
|
设计模式 消息中间件 算法
史上最全的24种设计模式的总结及建议+马士兵精讲Java设计模式
设计模式大杂烩(24种设计模式的总结及学习设计模式的几点建议)模式分类 & 传送门 & 对比维度说明 设计原则:设计模式(总纲) 创建型:单例模式 简单工厂模式 工厂方法模式 抽象工厂模式 建造者模式 原型模式 结构型:代理模式 适配器模式 装饰器模式 桥接模式 组合模式 享元模式 外观模式 行为型: 观察者模式 模板方法模式 命令模式 状态模式 职责链模式 解释器模式 中介者模式 访问者模式 策略模式 备忘录模式 迭代器模式