gpt4 book ai didi

pointers - 如何递归传递可变引用?

转载 作者:行者123 更新时间:2023-11-29 08:30:05 29 4
gpt4 key购买 nike

我正在尝试解决 this problem在 Rust 中。

这是我的非编译 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

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()

我知道这个特定的实现并不理想,但我只是想学习这门语言。我试图只将 HashMap 的引用传递给函数。在不改变解决此问题的方法的情况下,我如何使用可变的 HashMap 引用(如果可能的话)?

最佳答案

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

fibs 已经 是可变引用。在函数中,您说 &mut fibs,这将获得对可变引用的可变引用。这没有用,并且与正确的类型不匹配。相反,直接传递 fibs

然后你必须拆分两个子调用:

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

这最后一点是借用检查器的局限性——使用 &mut 接收器的嵌套方法调用会导致借用错误,但是将它们分成单独的语句可以解决这个问题。


作为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.

这反射(reflect)在编译器错误消息中:

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

确实,进行建议的更改可以让代码继续处理下一个错误。但是,像这样的嵌套引用会使事情变得过于复杂,因此最好保持适当数量的引用。

关于pointers - 如何递归传递可变引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38034912/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com