Сохранение переменной при нескольких вызовах функций в ржавчине

Я пытаюсь запомнить рекурсивную функцию последовательности коллаца в ржавчине, однако мне нужна хэш-карта запомненных значений, чтобы сохранить ее содержимое при отдельных вызовах функций. Есть ли элегантный способ сделать это в ржавчине, или мне нужно объявлять хэш-карту в main и каждый раз передавать ее функции? Я считаю, что хэш-карта переопределяется как пустая карта каждый раз, когда я вызываю функцию. Вот мой код:

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);
}

Кстати, зачем мне добавлять все символы & и *, когда я вставляю и извлекаю элементы из HashMap? Я просто сделал это, потому что компилятор жаловался, и добавление их исправило, но я не уверен, почему. Разве я не могу просто пройти по значению? Спасибо.


person picklebobdogflog    schedule 31.03.2014    source источник


Ответы (2)


Вы можете использовать thread_local для локальной статики потока.

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. Также есть отличный макрос lazy-static, который можно использовать для действительно глобальных статических кэшей. Вот пример.

person ArtemGr    schedule 14.08.2014
comment
ссылка на local_data не работает - person Gevious; 02.06.2015

В Rust нет «статических» локальных переменных, как в C, нет. Может быть, создать объект, поместить в него хеш и сделать collatz его методом.

Вы не можете передавать по значению, потому что это либо копирует (что может быть дорого для сложных ключей), либо перемещает (что сделает вас неспособным снова использовать ключ). В этом случае ваши ключи — это просто целые числа, но API предназначен для работы с произвольными типами.

person Eevee    schedule 31.03.2014