Closure需要对lambda函数的唯一访问

时间:2014-11-15 05:25:32

标签: rust borrow-checker

我正在学习Rust,并且已经实现了一些简单的代码来试验闭包 - 但我遇到了借用检查器的问题,我不确定如何解决。

编译以下功能时

fn twice(x:int, f:|int| -> int) -> int {
    f(f(x))
}

我收到以下错误

closure requires unique access to `f` but it is already borrowed

我正在完成指南,并对借款检查员为何不喜欢这一点有一个适度的理解 - 但我不确定如何解决它。

我可以通过首先将第一次调用的结果分配给临时变量,然后再次调用f(..)来解决它。然而,这感觉不够优雅。

是否有更清晰/更好的方式来编写f(f(x)),或某种方式来说服编译器这是安全的?

2 个答案:

答案 0 :(得分:3)

完整的错误消息是:

<anon>:2:7: 2:8 error: closure requires unique access to `f` but it is already borrowed
<anon>:2     f(f(x))
               ^
<anon>:2:5: 2:6 note: previous borrow of `f` occurs here; the unique capture prevents subsequent moves or borrows of `f` until the borrow ends
<anon>:2     f(f(x))
             ^
<anon>:2:12: 2:12 note: previous borrow ends here
<anon>:2     f(f(x))
                   ^

也就是说,在某种意义上,外部调用是保留f并阻止它首先被使用。这与issue #6268非常相似,它涉及方法而不是闭包。

正如您所说,使用临时修复是最合理的修复。

fn twice(x:int, f:|int| -> int) -> int {
    let y = f(x);
    f(y)
}

答案 1 :(得分:0)

在现代Rust中,原始代码按原样编译:

fn twice(x: i32, f: impl Fn(i32) -> i32) -> i32 {
    f(f(x))
}

fn main() {
    twice(42, |i| dbg!(i));
}