Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keeping a variable alive across multiple function calls in rust

I am trying to memoize a recursive collatz sequence function in rust, however I need the hashmap of memoized values to keep its contents across separate function calls. Is there an elegant way to do this in rust, or do I have to declare the hashmap in main and pass it to the function each time? I believe the hashmap is being redeclared as an empty map each time I call the function. Here is my code:

fn collatz(n: int) -> int {
    let mut map = HashMap::<int, int>::new();
    if map.contains_key(&n) {return *map.get(&n);}
    if n == 1 { return 0; }
    map.insert(n, 
        match n % 2 {
            0 => { 1 + collatz(n/2) }
            _ => { 1 + collatz(n*3+1) }
        }
    );
    return *map.get(&n);
}

On a side note, why do I need to add all of the &'s and *'s when I am inserting and pulling items out of the HashMap? I just did it because the compiler was complaining and adding them fixed it but I'm not sure why. Can't I just pass by value? Thanks.

like image 832
picklebobdogflog Avatar asked Mar 31 '14 02:03

picklebobdogflog


2 Answers

You can use thread_local for thread-local statics.

thread_local! (static COLLATZ_MEM: HashMap<i32, i32> = HashMap::new());
fn collatz(n: i32) -> i32 {
    COLLATZ_MEM.with (|collatz_mem| {
        0  // Your code here.
    })
}

P.S. There's also an excellent lazy-static macro which can be used for the truly global static caches. Here's an example.

like image 124
ArtemGr Avatar answered Nov 15 '22 08:11

ArtemGr


There are no "static" locals in Rust the way there are in C, no. Maybe make an object, put the hash in it, and make collatz a method of it.

You can't pass by value because that does either a copy (which might be expensive for complex keys) or a move (which would make you unable to use the key again). In this case your keys are just ints, but the API is meant to work for arbitrary types.

like image 29
Eevee Avatar answered Nov 15 '22 07:11

Eevee