有没有办法创建像这个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)
| ^^
答案 0 :(得分:14)
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
被借用。