由于“无法在Fn项目中捕获动态环境",因此无法创建本地功能. [英] Unable to create a local function because "can't capture dynamic environment in a fn item"

查看:35
本文介绍了由于“无法在Fn项目中捕获动态环境",因此无法创建本地功能.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么办法可以创建像这样的Python代码这样的局部函数?

Is there any way to create a local function like this Python code?

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

我尝试过,但是失败了:

I tried it, but failed:

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中的本地"功能实际上只是一个全局不可见的全局功能.除了其他全局函数外,它无能为力.

Functions in Rust don't capture variables from the surrounding environment, period. A "local" function in Rust is really just a global function that isn't globally visible; it can't do anything more than any other global function.

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

Instead, Rust has closures which are distinct from functions in that they do capture variables from their environment. That would look like this:

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

与此有关的三件事.首先, append 不是您想要的,您想要 push .您应检查 Vec 文档.>查看可用的方法以及可用的方法.其次,您必须使 a 可变,因为它会使捕获的内容发生突变(另请参见此

Three things to note with this. Firstly, append is not what you want, you want push. You should check the documentation for Vec to see what's available and what methods do. Secondly, you have to make a mutable because it's mutating something it captured (see also this answer about Fn, FnMut, and FnOnce). Third, it won't compile:

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 .您需要缩短借入的时间:

The problem is that by creating the closure, you had to give it a mutable borrow to ff. However, that borrow prevents anyone else from moving or otherwise messing with ff. You need to shorten the length of time this borrow exists:

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

这有效,但有点笨拙.这也是不必要的.只需将对 ff 的借用显式传递到本地函数中,就可以更清楚地重写上述内容:

This works, but is kinda clunky. It's also unnecessary; the above could more cleanly be rewritten by just passing the borrow to ff into a local function explicitly:

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 的内容保持整洁.

This last one is the best (if you're able to use it), because it keeps it clean when and why ff is being borrowed.

这篇关于由于“无法在Fn项目中捕获动态环境",因此无法创建本地功能.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆