2016-06-26 6 views
0

私は錆でthis problemを解決しようとしています。どのように再帰的に可変参照を渡すのですか?

use std::collections::HashMap; 
fn main() { 
    // initialize HashMap 
    let mut fibs: HashMap<u32, u32> = HashMap::new(); 
    fibs.insert(0, 1); 
    fibs.insert(1, 1); 
    let mut n = 1; 
    let mut sum = 0; 
    while fib(n, &mut fibs) < 4000000 { 
     sum += if fib(n, &mut fibs) % 2 == 0 {fib(n, &mut fibs)} else {0}; 
     n += 1; 
    } 
    println!("{}", sum); 
} 
fn fib(n:u32, fibs: &mut HashMap<u32, u32>) -> u32 { 
    if !fibs.contains_key(&n) { 
     fibs.insert(n, fib(n-1, &mut fibs)+fib(n-2, &mut fibs)); 
    } 
    *fibs.get(&n).unwrap() 
} 

錆のpython3翻訳に次のようになります:ここで

は私の非コンパイル錆コードがある

def main(): 
    fibs = {} 
    fibs[0] = 1 
    fibs[1] = 1 
    n = 1 
    summ = 0 
    while fib(n, fibs) < 4000000: 
     summ += fib(n, fibs) if fib(n, fibs) % 2 == 0 else 0 
     n+=1 
    print(summ) 
    print(fibs) 
def fib(n, fibs): 
    if n not in fibs: 
     fibs[n] = fib(n-1, fibs) + fib(n-2, fibs) 
    return fibs[n] 
main() 

私は、この特定の実装が理想的ではないことを理解し、私はもっぱらです言語を学ぶことを試みる。私は関数にハッシュマップの参照を渡すしようとしています。この問題を解決するアプローチを変更することなく、可能であればどのように変更可能なHashMapの参照を使用することができますか?

答えて

1
fn fib(n:u32, fibs: &mut HashMap<u32, u32>) -> u32 

fibsはすでに変更可能な参照です。この関数では、&mut fibと言っています。これは、可変参照への可変参照を取得します。これは有用ではなく、正しいタイプと一致しません。

はその後、2つの子コールを分割する必要があります。

fn fib(n: u32, fibs: &mut HashMap<u32, u32>) -> u32 { 
    if !fibs.contains_key(&n) { 
     let a = fib(n - 1, fibs); 
     let b = fib(n - 2, fibs); 
     fibs.insert(n, a + b); 
    } 
    *fibs.get(&n).unwrap() 
} 

この最後のビットがボローチェッカー意志hopefully be resolved by MIRの制限です。現在、受信者が&mutのネストされたメソッド呼び出しは借用エラーになりますが、それらを別々のステートメントに分割することで問題が解決されます。 delnan points outとして


変更可能な参照に変更可能な参照を服用することは有益ではなく、いくつかの混乱を示していますがDEREF強制型変換が&mut T&mut &mut Tを回すことができるので、それは、通常タイプのエラーではありません少なくともコンパイラが&mut Tが期待されることを知っているときは。

これは、コンパイラのエラーメッセージが言うに反映されます。

error: cannot borrow immutable argument `fibs` as mutable 
     fibs.insert(n, fib(n-1, &mut fibs)+fib(n-2, &mut fibs)); 
            ^~~~ 
help: to make the argument mutable, use `mut` as shown: 
fn fib(n:u32, mut fibs: &mut HashMap<u32, u32>) -> u32 { 

確かに、変更はコードは次のエラーに進むことを可能にすることになって。しかし、このようなネストされた参照を持つと事が過度に複雑になるので、適切な量の参照を保持することが望ましい。

+0

変更可能な参照に変更可能な参照を服用することは有益ではなく、いくつかの混乱を示していますがDEREF強制型変換はコンパイラが知っている、少なくとも '&MUT T '、に変身'&MUT&mutのT'ことができるので、それは、通常タイプのエラーではありません'' mut T''が期待されます。 – delnan

+0

@ljeabmreosnはい、それは昨晩の眠いの入力でした。今修正し、delnanのコメントで更新しました。 – Shepmaster

関連する問題