function - 无法创建本地函数,因为 "can' t 在 fn 项中捕获动态环境”

标签 function rust

有什么方法可以像这个 Python 代码一样创建本地函数吗?

def h():
    final = []
    def a():
        for i in range(5):
            final.append(i)
        a()
        return final

我试过了,但是失败了:

fn h() -> Vec<i32> {
    let mut ff = vec![];
    fn a() {
        for i in 0..5 {
            ff.push(i)
        }
    };
    a();
    ff
}
 error[E0434]: can't capture dynamic environment in a fn item; use the || { ... } closure form instead
 --> src/main.rs:5:13
  |
5 |             ff.push(i)
  |             ^^

最佳答案

Rust 中的函数不会从周围环境中捕获变量。 Rust 中的“本地”函数实际上只是一个全局不可见的全局函数;它不能做比任何其他全局函数更多的事情。

相反,Rust 具有不同于函数的闭包,因为它们确实从它们的环境中捕获变量。看起来像这样:

fn h() -> Vec<i32> {
    let mut ff = vec![];
    let mut a = || {
        for i in 0..5{
            ff.push(i)
        }
    };
    a();
    ff
}

这需要注意三点。首先,append 不是您想要的,您想要的是push。你应该检查 documentation for Vec查看可用的内容和方法。其次,您必须使 a 可变,因为它正在改变它捕获的内容(另请参见 answer about Fn, FnMut, and FnOnce )。第三,它不会编译:

error[E0505]: cannot move out of `ff` because it is borrowed
 --> <anon>:9:9
  |
3 |         let mut a = || {
  |                     -- borrow of `ff` occurs here
...
9 |         ff
  |         ^^ move out of `ff` occurs here

问题在于,通过创建闭包,您必须向它借用 ff 的可变内容。但是,这种借用可以防止其他任何人移动或以其他方式弄乱 ff。您需要缩短此借用存在的时间长度:

fn h() -> Vec<i32> {
    let mut ff = vec![];
    {
        let mut a = || {
            for i in 0..5{
                ff.push(i)
            }
        };
        a();
    }
    ff
}

这可行,但有点笨拙。这也是不必要的;上面的代码可以更干净地重写,只需将对 ff 的借用显式传递给本地函数即可:

fn h() -> Vec<i32> {
    let mut ff = vec![];
    fn a(ff: &mut Vec<i32>) {
        for i in 0..5{
            ff.push(i)
        }
    }
    a(&mut ff);
    ff
}

最后一个是最好的(如果您能够使用它的话),因为它在何时以及为什么要借用 ff 时保持干净。

关于function - 无法创建本地函数,因为 "can' t 在 fn 项中捕获动态环境”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42895596/

相关文章:

javascript - 使用 jQuery 的购物 list

我可以通过同时索引 c 中的两个矩阵来将矩阵的值传递给另一个矩阵吗?

rust - 在 Rust 中可变借用文字的语义是什么?

rust - 为什么在 Rust 中写入文件时会出现 "bad file descriptor"错误?

debugging - GDB `run` 命令失败并显示 "Cannot insert breakpoint 1."

sql - 直接从用户定义的函数中选择 xml 节点

c 将函数指针赋值给变量

rust - 如何在稳定的 Rust 中分配原始可变指针?

带函数的计算器

rust - 无法移出此处发生移动,因为 `slice[_]` 的类型为 `T` ,该类型未实现 `Copy` 特征