特征返回迭代器

时间:2016-11-26 21:55:24

标签: rust lifetime

我正在使用一个特性,需要一个函数返回迭代器而不消耗该对象。迭代器本身返回数据值的副本,而不是引用。由于迭代器实现需要对它正在迭代的对象的引用,我最终必须声明大量的生命周期(超过我认为必要的,但不能让它编译否则)。然后我在借用期限遇到麻烦 - 最小的工作"示例如下:

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条评论)。

0 个答案:

没有答案