Rustにおけるクロージャ(closure)とは、いわゆる無名関数のことです
structを使用する
クロージャで直接再帰を書く方法は現在のところ無いようです。参考
そこで関数を保持するstructを用います。なるほど。(参考 <- a great example!)
fn main() {
struct Fact<'s> {
f: &'s dyn Fn(&Fact, u32) -> u32,
}
let fact = Fact {
f: &|fact, x| if x == 0 { 1 } else { x * (fact.f)(fact, x - 1) },
};
println!("{}", (fact.f)(&fact, 5));
}
再帰クロージャを別の関数に渡したいとき
無名クロージャを引数として別の関数に渡したいときはRcとRefCellを使うと書けます
use std::rc::Rc;
use std::cell::RefCell;
struct Fact<'s> {
f: &'s dyn Fn(&Fact, u32) -> u32,
}
fn main() {
let f = Rc::new(RefCell::new(None));
let g = f.clone();
*g.borrow_mut() = Some(Fact {
f: &|fact, x| if x == 0 { 1 } else { x * (fact.f)(fact, x - 1) },
});
some_fn(f.borrow().as_ref().unwrap());
}
fn some_fn(f: &Fact) {
println!("{}", (f.f)(f, 5));
}
structが関数の外に出てしまいましたが、割とすっきり書けました。