1

我正在学习 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)),或者有什么方法可以让编译器相信这是安全的?

4

2 回答 2

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)
}
于 2014-11-15T05:51:30.730 回答
0

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

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

fn main() {
    twice(42, |i| dbg!(i));
}
于 2020-06-22T15:02:07.300 回答