Flutter/Dart中Iterable.contains无法识别嵌套数组的问题排查
问题根源:List是引用类型,默认判断引用相等
Dart 里的 List 属于引用类型,默认的 == 运算符和 contains 方法判断的是对象引用是否相同,而非列表内容是否一致。你每次写 <int>[1920, 1080] 都会创建一个全新的 List 对象,和集合里已有的 [1920, 1080] 不是同一个内存地址的对象,所以不管是循环里的 == 还是 contains 都会返回 false。
至于你看到的 JSArray,这只是 Dart 在 Web 环境(DartPad/Chrome)编译后的运行时类型,本质还是 List,它不是导致匹配失败的原因——哪怕在原生 Dart 环境(比如桌面端),普通 List 同样遵循引用相等的规则。
解决方法
方法1:手动比较列表元素
最直接的方式,遍历集合时逐个对比列表中的每个元素:
void main() { var someResolutions = <List<int>>[ [1920, 1080], [1920, 961], [961, 1920], [1366, 768], [1536, 864], [1280, 720], [1440, 900], [1600, 900] ]; // 循环匹配 for (List<int> resolution in someResolutions) { bool matches = resolution[0] == 1920 && resolution[1] == 1080; print('Does it match? $matches'); } // 使用any判断是否存在 bool exists = someResolutions.any((res) => res[0] == 1920 && res[1] == 1080); print(exists); // 输出true }
方法2:自定义类并重写==和hashCode
如果需要频繁做这类判断,建议封装成自定义类,重写相等判断逻辑:
class Resolution { final int width; final int height; Resolution(this.width, this.height); // 重写==,按内容判断相等 @override bool operator ==(Object other) => identical(this, other) || other is Resolution && runtimeType == other.runtimeType && width == other.width && height == other.height; // 必须同时重写hashCode,保证集合类(比如Set)的正常工作 @override int get hashCode => width.hashCode ^ height.hashCode; } void main() { var someResolutions = <Resolution>[ Resolution(1920, 1080), Resolution(1920, 961), Resolution(961, 1920), // ...其他分辨率 ]; bool matches = someResolutions.contains(Resolution(1920, 1080)); print(matches); // 输出true }
方法3:使用Dart 3.0+的记录类型(Records)
Dart 3.0及以上支持记录类型,记录是值类型,默认按内容比较相等,非常适合这种整数对场景:
void main() { var someResolutions = <(int, int)>[ (1920, 1080), (1920, 961), (961, 1920), // ...其他分辨率 ]; bool matches = someResolutions.contains((1920, 1080)); print(matches); // 输出true }
内容的提问来源于stack exchange,提问作者Quentin Kramer
相关产品推荐
相关产品推荐

