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)
| ^^
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.
Instead, Rust has closures which are distinct from functions in that they do capture variables from their environment. That would look like this:
Three things to note with this. Firstly,
append
is not what you want, you wantpush
. You should check the documentation forVec
to see what's available and what methods do. Secondly, you have to makea
mutable because it's mutating something it captured (see also this answer aboutFn
,FnMut
, andFnOnce
). Third, it won't compile: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 withff
. You need to shorten the length of time this borrow exists: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: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.