2014-07-07 53 views
2

我正试图在Rust中实现一个动态编程问题,以便熟悉该语言。像许多动态编程问题一样,这使用记忆来减少运行时间。不幸的是,我的第一通解决方案会产生错误。我已经将代码缩减到以下。警告 - 它现在是一个有点无厘头:为什么Rust想每次借用一个变量作为多次变量?

use std::collections::HashMap; 

fn repro<'m>(memo: &'m mut HashMap<i32, Vec<i32>>) -> Option<&'m Vec<i32>> { 
    { 
     let script_a = repro(memo); 
     let script_b = repro(memo); 
    } 

    memo.get(&0) 
} 

fn main() {} 

的编译错误是:

error[E0499]: cannot borrow `*memo` as mutable more than once at a time 
--> src/main.rs:6:30 
    | 
5 |   let script_a = repro(memo); 
    |        ---- first mutable borrow occurs here 
6 |   let script_b = repro(memo); 
    |        ^^^^ second mutable borrow occurs here 
7 |  } 
    |  - first borrow ends here 

为什么可变memo借多次?在我看来,当我计算script_a时应该借一次,那借款就结束了,然后再借用script_b

回答

3

目前借用过去的,只在定义(#9113可能会改变这一点,如果实现)块

的问题是,script_a(保持一个不变的参照地图)是适用于整个块,并尝试使用可变引用的相同地图:

let script_a = repro(memo); 
let script_b = repro(memo); 
// script_a is still alive 
+0

如果是'script_a'持有一个不可变引用的事实,那么为什么错误消息会说它想要拥有多个可变引用?我期望一个变体不能得到可变参考,而一个不可变参考生活错误信息。 – Shepmaster

+0

@Shepmaster生命周期在'&mut'输入参数上,也就是说'repro'调用正在使用'memo'。 – huon

+0

@dbaupp据我所知,'repro'获得了一个可变引用,但在第一次调用'repro'后,该引用不再有效。然而,'repro'从'script_a'所持有的HashMap中返回一个* immutable *引用。在第二次调用时,需要一个* mutable *引用,但有一个优秀的* immutable *引用('script_a')。因此,我希望这个错误表明我不能在一个不可变引用处于活动状态时获取可变引用。 – Shepmaster

0

更大的问题是无限循环。无论如何let script_a是哈希映射内部的数据的参考,所以在您拨打let script_b = repro(memo);时仍会借用它。

+0

是的,无限循环就是为什么我说“警告 - 现在有点儿了荒谬的“:-)。如果我正确理解你,你同意@ arjan的评估:'script_a'持有对来自HashMap的数据的引用;任何想法为什么它抱怨多个* mutable *引用,而不是一个可变和一个不可变? – Shepmaster

+0

嗯,如果没有一些猜测,我不能给你一个确切的答案,但它没有任何差别,你不能可变地借用已经借来的东西(可变或不可变)。你想在你的真实代码中做什么? –