由于“无法在Fn项目中捕获动态环境",因此无法创建本地功能. [英] Unable to create a local function because "can't capture dynamic environment in a fn item"
问题描述
有什么办法可以创建像这样的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屋!