Rust &引用;“活得不够长”;遍历链接列表时出错

Rust &引用;“活得不够长”;遍历链接列表时出错,rust,Rust,我试图创建一个链表和一个迭代器来遍历列表 enum List<T> { Cons(T, Box<List<T>>), Nil, } struct ListIterator<'a, T:'a> { cur: &'a List<T> } impl<'a, T> Iterator<T> for ListIterator<'a, T> { fn next(&

我试图创建一个链表和一个迭代器来遍历列表

enum List<T> {
    Cons(T, Box<List<T>>),
    Nil,
}

struct ListIterator<'a, T:'a> {
    cur: &'a List<T>
}

impl<'a, T> Iterator<T> for ListIterator<'a, T> {
    fn next(&mut self) -> Option<T>{
        match self.cur {
            &Cons(val, next) => {self.cur = &*next; Some(val)},
            &Nil => None
        }
    }
}

错误消息指出了一个真正的问题,但实际上编译器应该报告另一个问题,因为它出现得更早。在你的火柴臂上

&Cons(val, next) => {self.cur = &*next; Some(val)},
您正试图将列表对象分解为
&Cons(val,next)
,这是试图从借用的指针后面移出
val
next
。这是不允许的。但如果是这样,
val
next
将是局部变量,其生存期相当短。您看到的错误消息是因为:下一个是将要删除的本地框。因此,
&*next
的类型是一个引用,其生存期参数引用此本地框的生存期。这太短了,不能退了

这需要使用
ref
box
模式:

&Cons(ref val, box ref next) => { self.cur = next; Some(*val) },
现在,
val
属于
&T
类型,
next
属于
&List
类型,两者都是对列表数据结构的引用,没有任何内容被移出。还要注意的是,
Some(*val)
要求
T
Copy

impl<'a, T: Copy> Iterator<T> for ListIterator<'a, T> {
...

这适用于更多类型。如果你不想克隆这些值,你也可以让迭代器产生
&t
,而不是
t
,就像它对向量和切片所做的那样。

这不起作用。似乎我无权取消对val的引用。指向测试代码的链接:@lovasoa:如果我为t添加
Copy
绑定,它对我有效。正如我所说,t需要
Copy
。@lovasoa:Clone比Copy更通用。但是您可能应该实现
Iterator
,而不是
Iterator
。请参阅我的最新答案。
impl<'a, T: Copy> Iterator<T> for ListIterator<'a, T> {
...
impl<'a, T: Clone> Iterator<T> for ListIterator<'a, T> {
...
    &Cons(ref val, box ref next) => { self.cur = next; Some((*val).clone()) },