Dart中按引用传递的Future为何哈希值不同、比较结果为false?
Dart中Future比较不相等的原因分析及修正
问题核心
你第一个实验的逻辑是对的:当两个变量指向同一个Future实例时,引用相等,==返回true。但第二个实验的问题出在async函数的特性上,你忽略了async函数每次调用都会生成新的Future实例。
错误原因拆解
async函数的默认行为:
只要调用标记为async的函数,Dart会立即创建一个全新的Future实例作为函数返回值,不管你在函数内部return的是什么值(包括另一个Future)。这个新Future会等待你return的对象完成,然后传递其结果,但它本身是独立的实例。你的代码具体问题:
- 第一次调用
processFuture()时,async函数返回一个新Future(记为F1),也就是d1指向的实例。函数内部创建了_future,并await它。 - 第二次调用
processFuture()时,虽然进入了if (_future != null)分支并return _future,但async函数会把这个return的_future包装成另一个全新的Future(记为F2),也就是d2指向的实例。 F1和F2是两个不同的对象,所以哈希值不同,d1 == d2返回false。
补充说明:
init()里的两次processFuture()调用是同步执行的,此时第一次调用里的await _future还没执行到(因为Future.delayed是异步的),所以第二次调用时_future确实不为null,但返回的依然是新的Future实例。- 第一次调用
修正方案
要实现复用同一个Future的目标,需要让processFuture()直接返回_future实例,避免async函数的自动包装。可以把函数改成非async,用whenComplete处理后续逻辑:
void main() { Test(); } class Test { Future? _future = null; Test() { init(); } void init() { print("CALL 1"); Future d1 = processFuture(); print("ISNULL? "+(_future == null).toString()); print("CALL 2"); Future d2 = processFuture(); print("ISNULL? "+(_future == null).toString()); print(d1.hashCode); print(d2.hashCode); print(d1 == d2); // 现在会返回true } Future processFuture() { print("CALLED processFuture()"); if (_future != null){ print("FUTURE IS ALREADY THERE"); return _future!; } print("NEW FUTURE REQUESTED"); _future = Future.delayed(const Duration(seconds: 1)) .whenComplete(() { print("FUTURE COMPLETE"); _future = null; print("FUTURE IS NOW NULL"); }); print("NEW FUTURE CREATED"); return _future!; } }
这样修改后,两次调用processFuture()返回的都是同一个_future实例,d1 == d2会返回true,达到复用Future的目的。
内容的提问来源于stack exchange,提问作者g.imtech
相关产品推荐
相关产品推荐

