You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart/Flutter 不使用Equatable时如何判断两个对象是否逻辑等价

Dart类实例深度属性比较实现方案

不需要依赖Equatable包,也无需将属性标记为final,以下是两种常用落地实现:

方案1:手动逐字段对比(性能最优)

直接在类中自定义比较方法,按需实现基础类型、集合类型、自定义类型的深度对比,适合字段数量较少的类:

class User {
  // 无需标记为final
  String name;
  int age;
  List<String> tags;

  User({required this.name, required this.age, required this.tags});

  /// 深度比较两个实例属性是否完全一致
  bool isEqualTo(User other) {
    // 基础类型字段直接对比
    if (name != other.name || age != other.age) return false;
    // 集合类字段深度对比
    if (tags.length != other.tags.length) return false;
    for (int i = 0; i < tags.length; i++) {
      if (tags[i] != other.tags[i]) return false;
    }
    // 有自定义类属性的话,对应调用自定义类的比较方法即可
    // if (!customAttr.isEqualTo(other.customAttr)) return false;
    return true;
  }
}

// 调用示例
void main() {
  final userA = User(name: "张三", age: 20, tags: ["学生", "男性"]);
  final userB = User(name: "张三", age: 20, tags: ["学生", "男性"]);
  print(userA.isEqualTo(userB)); // 输出 true
  print(identical(userA, userB)); // 输出 false,不会判定为同一个内存实例
}

方案2:JSON序列化对比(开发效率最高)

如果类字段多、嵌套结构复杂,手动写对比逻辑成本高,可以通过序列化JSON字符串对比的方式实现,只要维护类的toJson方法即可:

import 'dart:convert';

class User {
  String name;
  int age;
  List<String> tags;

  User({required this.name, required this.age, required this.tags});

  Map<String, dynamic> toJson() => {
    "name": name,
    "age": age,
    "tags": tags,
    // 嵌套自定义类也要实现toJson方法
    // "customAttr": customAttr.toJson(),
  };

  bool isEqualTo(User other) {
    return jsonEncode(this) == jsonEncode(other);
  }
}

这种方案的优势是代码量少,嵌套结构适配成本低,普通业务场景性能足够,缺点是对比效率低于手动实现的方案。

注意事项

  • 两种方案都只会校验属性值的逻辑等价性,不会判断两个实例是否为同一个内存对象
  • 如果属性包含自定义类,需要给对应的自定义类也实现比较逻辑(方案1)或toJson方法(方案2),才能保证深度比较完全生效

内容的提问来源于stack exchange,提问作者kris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 15:42:00