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()) },