本文介绍了“活得不够久"遍历链表时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个链表和一个迭代器来遍历列表.

枚举列表{Cons(T, Box迭代器对于 ListIterator<'a, T>{fn next(&mut self) ->选项{匹配 self.cur {&Cons(val, next) =>{self.cur = &*next;一些(val)},&Nil =>没有任何}}}

但我收到以下错误:

错误:`*next` 存活时间不够长
解决方案

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

&Cons(val, next) =>{self.cur = &*next;一些(val)},

您正在尝试将 List 对象解构为 &Cons(val,next),这是尝试移动 valnext从借来的指针后面出来.这是不允许的.但如果是这样,valnext 将是生命周期相当短的局部变量.您看到的错误消息是因为:下一个将是即将被丢弃的本地框.因此,&*next 的类型是一个引用,其生命周期参数指的是这个本地框的生命周期.这太短了,无法退回.

这需要使用 refbox 模式:

&Cons(ref val, box ref next) =>{ self.cur = 下一个;一些(*val) },

现在,val 属于 &T 类型,next 属于 &List 类型,其中是对您的列表数据结构的引用,并且没有任何内容被移出.另请注意,Some(*val) 要求 TCopy:

impl迭代器对于 ListIterator<'a, T>{...

但是Copy 是一个相当大的要求.更通用的方法是像这样使用 Clone :

impl迭代器对于 ListIterator<'a, T>{...&Cons(ref val, box ref next) =>{ self.cur = 下一个;Some((*val).clone()) },

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

I'm trying to create a linked list and an iterator to iterate through the list.

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
        }
    }
}

But I get the following error:

error: `*next` does not live long enough
解决方案

The error message points to a real issue, but there is actually another one that the compiler should report instead because it comes earlier. In your match arm

&Cons(val, next) => {self.cur = &*next; Some(val)},

you are trying to destructure a List object into &Cons(val,next) which is an attempt to move val and next out from behind a borrowed pointer. This is not allowed. But if it were, val and next would be local variables with a rather short lifetime. The error message you see is because of that: next would be a local box that is about to be dropped. Hence the type of &*next is a reference with a lifetime parameter referring to the lifetime of this local box. And that's too short to return it.

This calls for the use of ref and box patterns:

&Cons(ref val, box ref next) => { self.cur = next; Some(*val) },

Now, val is of type &T and next is of type &List where both are references into your list data structure and nothing is moved out. Note also, that Some(*val) requires T to be Copy:

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

But Copy is quite a requirement. A more general way would be to use Clone like this:

impl<'a, T: Clone> Iterator<T> for ListIterator<'a, T> {
...
    &Cons(ref val, box ref next) => { self.cur = next; Some((*val).clone()) },

This works for more types. And if you don't want to clone the values, you could also make your iterator yield &T instead of T just like it's done with vectors and slices.

这篇关于“活得不够久"遍历链表时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 06:26