Is it possible to make a recursive closure in Rust?

后端 未结 2 518
情话喂你
情话喂你 2020-11-27 18:38

This is a very simple example, but how would I do something similar to:

let fact = |x: u32| {
    match x {
        0 => 1,
        _ => x * fact(x - 1         


        
2条回答
  •  爱一瞬间的悲伤
    2020-11-27 18:54

    Here's a really ugly and verbose solution I came up with:

    use std::{
        cell::RefCell,
        rc::{Rc, Weak},
    };
    
    fn main() {
        let weak_holder: Rc u32>>> =
            Rc::new(RefCell::new(Weak:: u32>::new()));
        let weak_holder2 = weak_holder.clone();
        let fact: Rc u32> = Rc::new(move |x| {
            let fact = weak_holder2.borrow().upgrade().unwrap();
            if x == 0 {
                1
            } else {
                x * fact(x - 1)
            }
        });
        weak_holder.replace(Rc::downgrade(&fact));
    
        println!("{}", fact(5)); // prints "120"
        println!("{}", fact(6)); // prints "720"
    }
    

    The advantages of this are that you call the function with the expected signature (no extra arguments needed), it's a closure that can capture variables (by move), it doesn't require defining any new structs, and the closure can be returned from the function or otherwise stored in a place that outlives the scope where it was created (as an Rc) and it still works.

提交回复
热议问题