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

标签 pointers rust

我正在尝试解决 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/

相关文章:

hash - 为什么我的程序错误地计算了MD2哈希?

rust - 通过变量访问结构字段

c - 返回 Void 指针截断值

c - 从指针中减去得到长度

c++ - 传递指向 API 函数的指针

rust - 如何反序列化没有给定长度的 bincode 字段

c - C中的双指针

c - 原始类型声明在 C 中如何工作?

rust - 有没有办法从数组构造条件?

rust - 无法在安全的 Rust 中创建循环链表;不安全版本崩溃