首页 > 解决方案 > 是否可以检查 rust 中的闭包是否相等?

问题描述

我对 rust 很陌生,但是对于我正在做的一个练习项目,我想实现一个类似 API 的 React useMemo,我想如果闭包的类型是静态的,并且捕获变量存储在某个地方,我应该无法检查平等?

就像是:

let cached = scope.use_memo(move || {
    complicated_computation(captured_variable)
});

其中 use_memo 类似于

pub fn use_memo<F: Fn() -> T + PartialEq + 'static, T: Clone + 'static>(&mut self, factory: F) -> &T

在代码中,我可以将 factory 与之前存储的 factory 函数进行比较,并决定是否需要重新运行 factory。

显然这不起作用,因为闭包没有实现PartialEq,但我想知道是否有办法实现它。

标签: rustclosuresprogramming-languages

解决方案


不,每个闭包都有一个单独的类型,即使它们是相同的,你也不能比较交叉类型。

一个最小的例子

fn main() {
    let b = 2;
    let a = if true {
        || println!("{}", b)
    } else {
        || println!("{}", b)
    };
}

我们得到一个编译器错误,它有助于解释没有两个闭包,即使是相同的,也有相同的 type

Compiling playground v0.0.1 (/playground)
error[E0308]: `if` and `else` have incompatible types
 --> src/main.rs:6:9
  |
3 |       let a = if true {
  |  _____________-
4 | |         || println!("{}", b)
  | |         -------------------- expected because of this
5 | |     } else {
6 | |         || println!("{}", b)
  | |         ^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure
7 | |     };
  | |_____- `if` and `else` have incompatible types
  |
  = note: expected type `[closure@src/main.rs:4:9: 4:29 b:_]`
          found closure `[closure@src/main.rs:6:9: 6:29 b:_]`
  = note: no two closures, even if identical, have the same type
  = help: consider boxing your closure and/or using it as a trait object

error: aborting due to previous error

您可以构建明确包含环境的结构并比较它们而不是使用闭包,但我建议重新考虑您的问题,看看这是否是解决它的最佳方法。


推荐阅读