在尝试重构一个本来运行良好的Rust应用程序时,我尝试将循环的内容分离到一个新函数中。然而,在这个新的重构出的函数中,我需要传递一个必须是可变的、通过引用传递的参数。突然间,仅仅因为可变引用传递的原因,绝对能够内联工作的代码就崩溃了。
我的问题是:有人可以解释一下为什么这个“简单”的更改不能使用吗?(即将未改变的代码重构成一个新函数)
我有一个最小化的问题演示,以及一些工作比较。以下是该代码的错误:
注意第一个循环(`int_to_int`)与第三个循环(`str_to_int`)除了键的数据类型外完全相同--即键不是引用,因此不需要指定生命周期。第二个循环(`str_to_int_inline`)与第三个循环(`str_to_int`)的行为相同,但是行为是内联的而不是在一个单独的函数中。
有许多相关的问题和博客涉及此主题,但它们似乎更具体地关注特定版本的问题,我想知道更一般的解释(根据我的当前理解)。如果答案已经在这些链接中了,我将很乐意标记此问题为重复。
相关问题:
我的问题是:有人可以解释一下为什么这个“简单”的更改不能使用吗?(即将未改变的代码重构成一个新函数)
我有一个最小化的问题演示,以及一些工作比较。以下是该代码的错误:
error[E0499]: cannot borrow `str_to_int` as mutable more than once at a time
--> src/main.rs:30:22
|
30 | get_key(key, &mut str_to_int);
| ^^^^^^^^^^^^^^^ `str_to_int` was mutably borrowed here in the previous iteration of the loop
示例代码:
use std::collections::BTreeMap;
fn get_int (
key: u32,
values: &mut BTreeMap<u32, u32>,
) -> &u32 {
values.entry(key).or_insert_with(|| { 1 })
}
fn get_key<'a> (
key: &'a str,
values: &'a mut BTreeMap<&'a str, u32>,
) -> &'a u32 {
values.entry(key).or_insert_with(|| { 1 })
}
fn main() {
let mut int_to_int = BTreeMap::new();
for key in vec![1,2] {
get_int(key, &mut int_to_int);
}
let mut str_to_int_inline = BTreeMap::new();
for key in vec!["a","b"] {
str_to_int_inline.entry(key).or_insert_with(|| { 1 });
}
let mut str_to_int = BTreeMap::new();
for key in vec!["a","b"] {
get_key(key, &mut str_to_int);
}
}
注意第一个循环(`int_to_int`)与第三个循环(`str_to_int`)除了键的数据类型外完全相同--即键不是引用,因此不需要指定生命周期。第二个循环(`str_to_int_inline`)与第三个循环(`str_to_int`)的行为相同,但是行为是内联的而不是在一个单独的函数中。
有许多相关的问题和博客涉及此主题,但它们似乎更具体地关注特定版本的问题,我想知道更一般的解释(根据我的当前理解)。如果答案已经在这些链接中了,我将很乐意标记此问题为重复。
相关问题:
- 如何在Rust中修复“.. was mutably borrowed here in the previous iteration of the loop”错误?
- https://users.rust-lang.org/t/mutable-borrow-starts-here-in-previous-iteration-of-loop/26145
- https://github.com/rust-lang/rust/issues/47680#issuecomment-363131420
- 为什么只有可变引用时链接生命周期才有意义?
我读到的一些内容还提到了https://github.com/rust-lang/polonius,似乎也可以在未来使其工作--你有什么想法吗?
'a
的内容都被删除。你能分离出key
和value
参数的生命周期吗?你的key
的生命周期与你的映射和返回值相同,这会使得你的返回值一直存在,直到vec!["a", "b"]
被删除,而这只会发生在main()
结束时。 - MeetTitanpolonius-the-crab
crate。 - chabapok