Flutter中operator ==方法是什么?结合BoxShadow实现解析
Flutter中
operator ==方法详解 基础概念
Dart语言支持运算符重载,operator就是用来声明重载运算符的关键字,operator ==就是对相等判断运算符==的自定义重载。默认Object类自带的==逻辑是判断两个对象是否指向同一内存实例,我们重写该方法,就可以自定义“两个对象相等”的判断规则。
BoxShadow的operator ==实现解析
官方BoxShadow类的重写代码如下:
@override bool operator ==(Object other) { if (identical(this, other)) return true; if (other.runtimeType != runtimeType) return false; return other is BoxShadow && other.color == color && other.offset == offset && other.blurRadius == blurRadius && other.spreadRadius == spreadRadius; }
逐行逻辑说明:
identical(this, other):优先判断两个对象是不是完全相同的内存实例,如果是直接返回相等,跳过后续属性判断,优化性能other.runtimeType != runtimeType:判断两个对象的运行时类型是否完全一致,比如BoxShadow的子类实例和父类实例对比会直接返回不相等,避免类型不匹配导致的错误判断- 最后一段逻辑先确认对比对象是BoxShadow类型,再挨个对比所有核心属性,所有属性值都相等才认为两个阴影对象是相等的
配套hashCode的作用
Dart有强制约定:如果重写了operator ==,必须同步重写hashCode属性。像Set、Map这类哈希结构的集合,判断元素是否重复时会先校验hashCode是否相等,只有hashCode相等才会调用==做二次判断,如果只重写==不修改hashCode,两个逻辑上相等的对象会被集合判定为不同元素,出现逻辑bug。
BoxShadow配套的hashCode实现如下:
@override int get hashCode => hashValues(color, offset, blurRadius, spreadRadius);
其中hashValues是Flutter提供的工具方法,可以把多个属性值组合生成一个哈希值,保证属性值相同的对象生成的哈希值也一致。
适用场景
- 自定义类需要按值判断相等:比如业务中的用户类、订单类,需要按业务字段(比如用户ID、订单ID)判断两个对象是否指代同一个业务实体时,就可以重写
==和hashCode - 框架性能优化:Flutter内置的Widget、装饰类(比如BoxShadow、Border)重写该方法后,框架做界面Diff更新时,就能快速判断配置是否发生变化,避免不必要的重绘
- 自定义类作为哈希集合元素:如果要把自定义类放入Set、或者作为Map的key使用,必须重写这两个方法,否则集合的去重、查询功能都会异常
简单示例
我们以自定义用户类为例,先看不重写的效果:
class User { final String id; final String name; User(this.id, this.name); } void main() { final user1 = User('1001', '张三'); final user2 = User('1001', '张三'); print(user1 == user2); // 输出false,默认判断内存地址,两个是不同实例 final userSet = <User>{user1, user2}; print(userSet.length); // 输出2,Set没有去重,因为两个对象hashCode不同 }
重写==和hashCode后的效果:
class User { final String id; final String name; User(this.id, this.name); @override bool operator ==(Object other) { if (identical(this, other)) return true; if (other.runtimeType != runtimeType) return false; // 业务规则:只要用户ID相同,就认为是同一个用户 return other is User && other.id == id; } @override int get hashCode => id.hashCode; // 哈希值和ID绑定,保证逻辑相等的对象哈希值一致 } void main() { final user1 = User('1001', '张三'); final user2 = User('1001', '张三'); print(user1 == user2); // 输出true,符合业务判断规则 final userSet = <User>{user1, user2}; print(userSet.length); // 输出1,Set正确完成去重 }
内容的提问来源于stack exchange,提问作者Pannam
相关产品推荐
相关产品推荐

