Dart文档称默认==仅判断对象是否identical,为何此处运行结果不符?
核心前提
你提到的「默认==运算符仅在对象完全相同(identical)时才判定二者相等」,指的是Dart顶层Object类的原生==实现,Dart大量内置类型都重写了==运算符实现自定义相等规则,所有现象的差异都来自该规则+运行平台的特性差异。
现象1:print(a == b)返回true的原因
String类明确重写了==运算符,规则为逐字符比较两个字符串的内容,只要内容完全一致就返回true,和两个字符串是否为内存中的同一个对象无关。因此即使a、b是分别通过插值生成的字符串,只要内容都是Hello World,==判断结果就为真。
现象2:identical结果在DartPad和VS Code中不一致的原因
identical的作用是判断两个变量是否指向内存中的同一个对象,结果差异来自运行环境的实现区别:
- DartPad默认将Dart编译为JavaScript在浏览器环境运行,JS的字符串、数字都为值类型,相同值的基础类型变量会自动指向同一引用,因此
identical(x, y)、identical(a, b)都返回true - VS Code中通常是直接在Dart VM本地运行代码,Dart VM仅会对编译时常量做规范化(canonicalize)处理:也就是同值的编译时常量会指向同一个对象。你代码中的字符串是运行时通过插值动态生成的、double是普通变量赋值,都不属于编译时常量,因此VM不会做内存驻留处理,两个同值变量是独立的对象,
identical返回false。如果将变量声明为const修饰的编译时常量,不管在哪种环境运行identical都会返回true。
现象3:eq3 == eq4、identical(eq3, eq4)返回false的原因
Dart的普通List没有重写==运算符,直接沿用Object的默认实现,也就是仅判断是否为同一对象:
eq3是const修饰的编译时常量列表,存储在常量池中eq4是运行时动态生成的普通列表,在堆内存中独立存储
两者是完全独立的对象,因此==和identical判断都返回false。如果需要比较两个列表的内容是否相等,需要使用flutter/foundation.dart库的listEquals方法。
内容的提问来源于stack exchange,提问作者Be happy
相关产品推荐
相关产品推荐

