简体   繁体   English

如何递归传递可变引用?

[英]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.

相关问题 如何在Rust中传递对可变数据的引用? - How do I pass a reference to mutable data in Rust? 如何通过引用传递工会成员 - How do I pass a member of a union by reference 当它是结构的属性时,如何通过引用传递多维数组? - How do I pass a multi-dimensional array by reference when it's a property of a struct? 如何将C ++引用传递给C函数的指针参数? - How do I pass a C++ reference, to a pointer argument of a C function? 如何避免在此程序中使用指针变量和基于指针的传递引用? - how do i avoid using pointer variables and pointer-based pass-by-reference in this program? 如何正确地将 class object 的引用传递给 C++ 中的另一个类对象 - How do I correctly pass a reference of a class object into another class-object in C++ 如何通过引用char * foo [SIZE] [SIZE]传递给函数并取消引用? - How do I pass by reference char * foo[SIZE][SIZE] to a function and dereference it? 如何将值传递给另一个函数(通过引用/值调用)? (C) - How do I pass values to another functions (call by reference/value)? (C) 如何通过引用传递此指针? - How can I pass this pointer by reference? 如何在Bada中将控件作为参考传递? - How can I pass controls as reference in Bada?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM