Recursion 带外变量的递归函数

Recursion 带外变量的递归函数,recursion,rust,scoping,Recursion,Rust,Scoping,我在变量作用域方面有点困难。我目前有类似以下代码: use std::collections::HashMap; fn main() { let mut cache: HashMap<usize, usize> = HashMap::new(); fn fib(n: usize) -> usize { // Special values if n == 0 || n == 1 { return 1;

我在变量作用域方面有点困难。我目前有类似以下代码:

use std::collections::HashMap;

fn main() {
    let mut cache: HashMap<usize, usize> = HashMap::new();

    fn fib(n: usize) -> usize {
        // Special values
        if n == 0 || n == 1 {
            return 1;
        }

        // Check if value is in cache
        if let Some(&a) = cache.get(&n) {
            return a;
        }

        // Calculate
        let f = fib(n - 2) + fib(n - 1);

        // Insert in cache for later use
        cache.insert(n, f);

        return f;
    }

    println!("The 11th Fibonacci number is: {}", fib(10));
}
修复了缓存错误,但在let f=..处给出了在此作用域中找不到函数'fib'的警告

我还尝试使用中所述的环境,但不喜欢我两次调用同一个函数,从而在环境中有可变缓存时借用环境两次


我该如何处理这种奇怪的情况?

您使用环境的方法是正确的,但是您需要确保所有需要可变的东西都是可变的:

use std::collections::HashMap;

fn main() {
    struct FibEnv { cache: HashMap<usize, usize> }

    fn fib(mut env: &mut FibEnv, n: usize) -> usize {
        // Special values
        if n == 0 || n == 1 {
            return 1;
        }

        // Check if value is in cache
        if let Some(&a) = env.cache.get(&n) {
            return a;
        }

        // Calculate
        let f = fib(&mut env, n - 2) + fib(&mut env, n - 1);

        // Insert in cache for later use
        env.cache.insert(n, f);

        return f;
    }

    let cache: HashMap<usize, usize> = HashMap::new();
    let mut env = FibEnv { cache: cache };
    println!("The 11th Fibonacci number is: {}", fib(&mut env, 10));
}
正如@Shepmaster在评论中所述,以下内容更为简单:

use std::collections::HashMap;

fn main() {
    fn fib(cache: &mut HashMap<usize, usize>, n: usize) -> usize {
        // Special values
        if n == 0 || n == 1 {
            return 1;
        }

        // Check if value is in cache
        if let Some(&a) = cache.get(&n) {
            return a;
        }

        // Calculate
        let f = fib(cache, n - 2) + fib(cache, n - 1);

        // Insert in cache for later use
        cache.insert(n, f);

        return f;
    }

    let mut cache: HashMap<usize, usize> = HashMap::new();
    println!("The 11th Fibonacci number is: {}", fib(&mut cache, 10));
}
我也尝试过使用环境。。。但我不喜欢我调用同一个函数两次。除了您没有向我们展示此尝试之外。在您的第一个示例中,至少有一个太多的mut:参数env不需要是mut,它从未分配给。
use std::collections::HashMap;

fn main() {
    fn fib(cache: &mut HashMap<usize, usize>, n: usize) -> usize {
        // Special values
        if n == 0 || n == 1 {
            return 1;
        }

        // Check if value is in cache
        if let Some(&a) = cache.get(&n) {
            return a;
        }

        // Calculate
        let f = fib(cache, n - 2) + fib(cache, n - 1);

        // Insert in cache for later use
        cache.insert(n, f);

        return f;
    }

    let mut cache: HashMap<usize, usize> = HashMap::new();
    println!("The 11th Fibonacci number is: {}", fib(&mut cache, 10));
}