我正在尝试解决Rust中的this problem。
这是我的非编译Rust代码:
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()
}
Rust to 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的引用传递给函数。如果不改变解决这个问题的方法,如果可能的话,如何使用可变的HashMap
引用呢?
答案 0 :(得分:1)
fn fib(n:u32, fibs: &mut HashMap<u32, u32>) -> u32
fibs
已经一个可变引用。在函数中,您说&mut fib
,它将获得对可变引用的可变引用。这没用,并且与正确的类型不匹配。
然后你必须分出两个孩子的电话:
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
接收器的嵌套方法调用会导致借用错误,但将它们分成单独的语句可以解决问题。
虽然对可变引用进行可变引用是没有用的并且表现出一些混淆,但它通常不是类型错误,因为deref强制可以将
&mut &mut T
转换为&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 {
确实,进行此更改允许代码继续执行下一个错误。但是,如果嵌套这样的引用过于复杂化,那么最好保留适当数量的引用。