我正在使用一个特性,需要一个函数返回迭代器而不消耗该对象。迭代器本身返回数据值的副本,而不是引用。由于迭代器实现需要对它正在迭代的对象的引用,我最终必须声明大量的生命周期(超过我认为必要的,但不能让它编译否则)。然后我在借用期限遇到麻烦 - 最小的工作"示例如下:
pub trait MyTrait<'a> {
type IteratorType: Iterator<Item=u32>;
fn iter(&'a self) -> Self::IteratorType;
fn touch(&'a mut self, value: u32);
}
struct MyStruct {
data: Vec<u32>
}
struct MyIterator<'a> {
structref: &'a MyStruct,
next: usize,
}
impl<'a> Iterator for MyIterator<'a> {
type Item = u32;
fn next(&mut self) -> Option<u32> {
if self.next < self.structref.data.len() {
self.next += 1;
return Some(self.structref.data[self.next-1]);
} else {
return None;
}
}
}
impl<'a> MyTrait<'a> for MyStruct {
type IteratorType = MyIterator<'a>;
fn iter(&'a self) -> Self::IteratorType {
return MyIterator { structref: &self, next: 0 };
}
fn touch(&'a mut self, value: u32) {
}
}
fn touch_all<'a,T>(obj: &'a mut T) where T: MyTrait<'a> {
let data: Vec<u32> = obj.iter().collect();
for value in data {
obj.touch(value);
}
}
编译它会给我一个错误:
error[E0502]: cannot borrow `*obj` as mutable because it is also borrowed as immutable
|
39 | let data: Vec<u32> = obj.iter().collect();
| --- immutable borrow occurs here
40 | for value in data {
41 | obj.touch(value);
| ^^^ mutable borrow occurs here
42 | }
43 | }
| - immutable borrow ends here
由于我对生命周期的理解有限,我认为不可变借用只会扩展到我创建它的行 - 在所有迭代器被消耗之后我不再持有对obj或其中包含的数据的任何引用。为什么借用的生命周期延伸到整个函数,我该如何解决这个问题?
以下是我到达此处的一系列步骤 - 运行代码应提供相关的编译器错误。
澄清:我希望能够拨打这样的电话:
fn main() {
let obj: MyStruct = MyStruct { data : vec![] };
touch_all(&mut obj);
}
而不是必须致电
touch_all(&mut &obj);
这是mcarton提案所需要的(第1和第2条评论)。