[英]How do I recursively pass a mutable reference?
I am attempting to solve this problem in Rust.我正在尝试在 Rust 中解决这个问题。
Here is my non-compiling Rust code:这是我的非编译 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()
}
error[E0596]: cannot borrow `fibs` as mutable, as it is not declared as mutable
--> src/main.rs:22:35
|
20 | fn fib(n: u32, fibs: &mut HashMap<u32, u32>) -> u32 {
| ---- help: consider changing this to be mutable: `mut fibs`
21 | if !fibs.contains_key(&n) {
22 | fibs.insert(n, fib(n - 1, &mut fibs) + fib(n - 2, &mut fibs));
| ^^^^^^^^^ cannot borrow as mutable
error[E0499]: cannot borrow `fibs` as mutable more than once at a time
--> src/main.rs:22:35
|
22 | fibs.insert(n, fib(n - 1, &mut fibs) + fib(n - 2, &mut fibs));
| ---- ------ ^^^^^^^^^ second mutable borrow occurs here
| | |
| | first borrow later used by call
| first mutable borrow occurs here
error[E0596]: cannot borrow `fibs` as mutable, as it is not declared as mutable
--> src/main.rs:22:59
|
20 | fn fib(n: u32, fibs: &mut HashMap<u32, u32>) -> u32 {
| ---- help: consider changing this to be mutable: `mut fibs`
21 | if !fibs.contains_key(&n) {
22 | fibs.insert(n, fib(n - 1, &mut fibs) + fib(n - 2, &mut fibs));
| ^^^^^^^^^ cannot borrow as mutable
error[E0499]: cannot borrow `fibs` as mutable more than once at a time
--> src/main.rs:22:59
|
22 | fibs.insert(n, fib(n - 1, &mut fibs) + fib(n - 2, &mut fibs));
| ---- ------ first borrow later used by call ^^^^^^^^^ second mutable borrow occurs here
| |
| first mutable borrow occurs here
The Rust to Python3 translation looks like this: Rust 到 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()
I understand that this particular implementation is not ideal, but I am solely trying to learn the language.我知道这个特定的实现并不理想,但我只是想学习这门语言。 I am trying to only pass a reference of the hashmap to the function.
我试图只将哈希图的引用传递给函数。 Without changing the approach to solving this problem, how can I use mutable
HashMap
references, if it's even possible?在不改变解决这个问题的方法的情况下,如果可能的话,我如何使用可变的
HashMap
引用?
fn fib(n: u32, fibs: &mut HashMap<u32, u32>) -> u32 {
fibs
is already a mutable reference. fibs
已经是一个可变引用。 In the function, you say &mut fibs
, which would get a mutable reference to a mutable reference.在函数中,你说
&mut fibs
,它将获得对可变引用的可变引用。 That's not useful, and doesn't match the correct type.这没有用,并且与正确的类型不匹配。 Instead, pass
fibs
directly.相反,直接传递
fibs
。
Then you have to split out the two child calls:然后你必须拆分两个子调用:
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()
}
This last bit is a limitation of the borrow checker — nested method calls with &mut
receivers result in borrowing errors, but separating them into separate statements fixes the issue.最后一点是借用检查器的一个限制——使用
&mut
接收器的嵌套方法调用会导致借用错误,但将它们分成单独的语句可以解决这个问题。
As delnan points out :正如德尔南指出的那样:
While taking a mutable reference to a mutable reference is not useful and demonstrates some confusion, it is usually not a type error, since deref coercions can turn
&mut &mut T
into&mut T
, at least when the compiler knows that&mut T
is expected.虽然对可变引用进行可变引用并没有用并且会引起一些混淆,但它通常不是类型错误,因为 deref 强制可以将
&mut &mut T
转换为&mut T
,至少当编译器知道&mut T
是预期的时。
This is reflected in what the compiler error messages say:这反映在编译器错误消息所说的内容中:
error[E0596]: cannot borrow `fibs` as mutable, as it is not declared as mutable
--> src/main.rs:22:35
|
20 | fn fib(n: u32, fibs: &mut HashMap<u32, u32>) -> u32 {
| ---- help: consider changing this to be mutable: `mut fibs`
21 | if !fibs.contains_key(&n) {
22 | fibs.insert(n, fib(n - 1, &mut fibs) + fib(n - 2, &mut fibs));
| ^^^^^^^^^ cannot borrow as mutable
Indeed, making the suggested change allows the code to proceed to the next error.实际上,进行建议的更改允许代码继续处理下一个错误。 However, having nested references like this overcomplicates things, so it's preferred to keep to the appropriate amount of references.
但是,像这样嵌套引用会使事情变得过于复杂,因此最好保持适当数量的引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.