Способы, которые делают рекурсивное закрытие, мне не подходят из принятого ответа на вопрос:
Можно ли сделать рекурсивное закрытие в Rust?
Мое замыкание должно быть возвращено из функции, необходимо переместить переменную из окружения в нее и изменить ее.
Тогда я нахожу способ более подходящим для меня:
Анонимная рекурсия с замыканиями
use std::cell::RefCell;
fn main() {
let id = &(|a| a) as &Fn(u64) -> u64;
let (fib, fib_p): (_, RefCell<&Fn(u64) -> u64>);
fib_p = RefCell::new(id);
fib = |n: u64| {
if n < 2 {
n
} else {
(fib_p.borrow())(n - 2) + (fib_p.borrow())(n - 1)
}
};
*fib_p.borrow_mut() = &fib;
println!("{}", fib(10));
}
Приведенный выше код работает нормально.
Но мое замыкание необходимо вернуть из функции, поэтому оно не может быть ссылкой для предотвращениясправка, и мы не знаем размер замыкания во время компиляции, поэтому я использовал для этого умный указатель Box
.Код ниже выдает ошибку:
use std::cell::RefCell;
fn main() {
let id: Box<Fn(u64) -> u64> = Box::new(|a| a);
let (fib, fib_p): (Box<Fn(u64) -> u64>, RefCell<&Box<Fn(u64) -> u64>>);
fib_p = RefCell::new(&id);
fib = Box::new(|n: u64| {
if n < 2 {
n
} else {
(fib_p.borrow())(n - 2) + (fib_p.borrow())(n - 1)
}
});
*fib_p.borrow_mut() = &fib;
println!("{}", fib(10));
}
error[E0597]: `fib_p` does not live long enough
--> src/main.rs:12:15
|
8 | fib = Box::new(|n: u64| {
| -------- capture occurs here
...
12 | (&fib_p.borrow())(n - 2) + (&fib_p.borrow())(n - 1)
| ^^^^^ borrowed value does not live long enough
...
19 | }
| - borrowed value dropped before borrower
|
= note: values in a scope are dropped in the opposite order they are created