rust - 为什么这个简单的闭包会失败,而其他两个函数会成功?

标签 rust closures

我构建了一个无法工作的闭包示例,也找不到它不工作的任何原因。为什么最后一次关闭时编译失败?

Playground

struct S {}

fn filter<P>(predicate: P)
where
    P: Fn(&S) -> bool,
{
    predicate(&S {});
}

fn main() {
    // this works
    filter(|_s| true);

    // this also works
    fn cb1(_s: &S) -> bool {
        true
    }
    filter(cb1);

    // but this doesn't work
    let cb2 = |_s| true;
    filter(cb2);
}

输出:

error[E0631]: type mismatch in closure arguments
  --> /tmp/closure.rs:19:5
   |
18 |     let cb2 = |_s| true;
   |               --------- found signature of `fn(_) -> _`
19 |     filter(cb2);
   |     ^^^^^^ expected signature of `for<'r> fn(&'r S) -> _`
   |
note: required by `filter`
  --> /tmp/closure.rs:3:1
   |
3  | fn filter<P>(predicate: P) where P: Fn(&S) -> bool,
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0271]: type mismatch resolving `for<'r> <[closure@/tmp/closure.rs:18:15: 18:24] as std::ops::FnOnce<(&'r S,)>>::Output == bool`
  --> /tmp/closure.rs:19:5
   |
19 |     filter(cb2);
   |     ^^^^^^ expected bound lifetime parameter, found concrete lifetime
   |
note: required by `filter`
  --> /tmp/closure.rs:3:1
   |
3  | fn filter<P>(predicate: P) where P: Fn(&S) -> bool,
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

最佳答案

来自以下Type mismatches resolving a closure that takes arguments by referenceHow to declare a lifetime for a closure argument?看来解决方案是改变:

fn filter<P>(predicate: P)
where
    P: Fn(&S) -> bool,
{
    predicate(&S {});
}

fn filter<'a, P>(predicate: P)
where
    P: Fn(&'a S) -> bool,
{
    predicate(&S {});
}

虽然我不知道为什么。当闭包被内联指定与存储在变量中并稍后使用时,它似乎与推断的生命周期相关。但当 &S 不是返回的结果时,尚不清楚为什么 &S 需要 'a 生命周期。如果您明白这一点,请在评论中解释。

尽管这个问题已“解决”,但最初发布的精简失败案例实际上并不能帮助我解决真正的问题,因为我无法编辑遇到问题的代码源 https://docs.rs/walkdir/2.2.9/walkdir/struct.IntoIter.html#method.filter_entry

当我尝试将存储的回调传递到 filter_entry 方法时,问题就出现了。解决方案是在 filter_entry 签名中放入显式生命周期,如本文前面所述,但只有在您想要编辑第三方代码时才可以这样做。我认为不幸的是,这个特定问题的答案是“你不能使用带有 filter_entry 的存储闭包”

关于rust - 为什么这个简单的闭包会失败,而其他两个函数会成功?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58773989/

相关文章:

c++ - 在 C++11 中, "lambda function"与 "lambda expression"和 "closure"相同吗?

javascript - 这种模式是否会导致闭包中的循环引用?

closures - 什么时候在 Go 中使用匿名函数?

实例函数的 Python id 不一致

user-interface - 用冰 rust 画img

Rust 文件示例无法编译

rust - 使用 Rust 对齐功能(issue 33626)

xpath - 如何迭代使用 sxd_xpath 提取的节点的所有属性?

rust - "cycle detected when computing the supertrait"怎么解决?

python - Python将函数闭包的名称绑定(bind)存放在哪里?