时不时地,我在循环中遇到了关于借用(或不借用)可变变量的相同问题,最终我花时间编写了一个最小化示例。因此,代码有点愚蠢,但这是我能想到的突出问题的最短版本:
struct Association {
used: bool,
key: usize,
value: String,
}
impl Association {
fn new(key: usize, value: &str) -> Self {
Association{used: false, key: key, value: value.to_string()}
}
}
fn find_unused<'a>(data: &'a mut Vec<Association>) -> Option<&'a String> {
for k in 0.. {
for a in data {
if a.key == k && !a.used {
a.used = true;
return Some(&a.value);
}
}
}
None
}
fn main() {
let mut assoc = vec![
Association::new(7, "Hello"),
Association::new(9, "World")
];
println!("{}", find_unused(&mut assoc).unwrap());
println!("{}", find_unused(&mut assoc).unwrap());
}
由于
data
被移动了,所以将导致错误。如果我改为借用它,则会失败,因为它已经被借用了。我希望确切地理解发生了什么并如何一般地解决它. 特别的是,即使代码结构非常傻,我也不想更改它。我也不想实现变通方法,因为这只是一个最简示例:请假定循环的嵌套方式是“正确”的,即使在这种情况下它非常愚蠢, 当然它肯定是。我只想知道如何告诉借用检查器实际上发生的事情是可以接受的。我知道一种方法可以做到这一点:
fn find_unused<'a>(data: &'a mut Vec<Association>) -> Option<&'a String> {
for k in 0.. {
for j in 0..data.len() {
if data[j].key == k && !data[j].used {
data[j].used = true;
return Some(&data[j].value);
}
}
}
None
}
这段代码编译没有错误并且按照预期运行。据我的初步了解,应该有一种使用迭代器而不是索引来表达上述内容的方法,我想知道具体实现方式。
-Zpolonius
选项。至于我提供的解决方案,只是为了帮助你,还有一种使用迭代器的方法,如果你没有创建一个真正展示你使用情况的[MCVE],那么你不能抱怨。我不是魔术师。 - Stargateur