如何理解 rust 的单向链表( 五 )


这里会有一个新的api:: 可以将的数据取出来 , 然后返回一个里面对象的引用
// 通过上面的分析 , 我们知道这个Iter对象不能和之前的IntoIter一样 , 它应该是一个有属性的结构体 , 因为他要存放节点的指针信息 , 用于展示// pub struct Iter {//info: Option<&Node>,// }// 这么写之后 , 编译会爆:Option<&Node>中的type `T` may not live long enough , 也就是我们最早分析的 , 这里要涉及到生命周期的指定// 编译器报错也会提示 , 是不是要考虑给&Node加一个'a的生命周期参数// 原因就是struct中的元素如果是引用类型的 , 那就必须要求这个引用的生命长于这个struct , 否则这个指针可能会悬垂// pub struct Iter<'a, T> {//info: Option<&'a Node>,// }// 接下来就是要给他实现之前定义的iterator的trait// impl<'a, T>Iterator for Iter<'a, T> {//type Item = &T;////// 这里的self是Node节点的引用 , 因此是&self , 而又因为这个next要随着取出下一个换掉 , 因此还要是mut类型//fn next(&mut self) -> Option {//todo!()//}// }// 这里Item要指定是T类型的指针 , 因为定义好的next返回的是一个Option<&Node>// 但是当这么修改后:type Item = &T;会报错缺少生命参数 , 因此最后改成:type Item = &'a T;// pub struct Iter<'a, T> {//info: Option<&'a Node>,// }// // impl<'a, T>Iterator for Iter<'a, T> {//type Item = &'a T;// //// 这里的self要知道是Node节点的引用 , 因此是&self , 而又因为这个next要随着取出下一个换掉 , 因此还要是mut类型//fn next(&mut self) -> Option {//self.info.map(|node|{//// 将临时变量node中的数据返回 , 展示出去//&node.value//})//}// }// 上面在定义next时候 , 直接把node的value返回回去之后 , 是不是发现Iter的info没有指向下一个元素 , 这样就没办法再次next了// 因此在返回前还需要加一行内容 , 将self.info指向下一个node的指针:self.info = node.next.as_deref();// 最终代码:pub struct Iter<'a, T> {info: Option<&'a Node>,}impl<'a, T>Iterator for Iter<'a, T> {type Item = &'a T;// 这里的self要知道是Node节点的引用 , 因此是&self , 而又因为这个next要随着取出下一个换掉 , 因此还要是mut类型fn next(&mut self) -> Option {self.info.map(|node|{// 将self.info换成下一个节点数据 , node.next是一个Option类型 , 而Option.as_deref()可以获取定义关联类型的值的引用// 相当于多去掉一层self.info = node.next.as_deref();// 将临时变量node中的数据返回 , 展示出去&node.value})}}// 接下来再给List实现iter方法 , 将List转成Iter// 测试部分#[test]fn iter() {let mut list = List::new();list.push(1);list.push(2);list.push(3);let mut iter = list.iter();assert_eq!(iter.next(), Some(&3));assert_eq!(iter.next(), Some(&2));assert_eq!(iter.next(), Some(&1));assert_eq!(list.pop(), Some(3)); // 因为是引用迭代 , 因此并不影响源List可以pop()数据assert_eq!(list.pop(), Some(2));assert_eq!(list.pop(), Some(1));}
part3: 可变引用:
分析和part2一样 , 只不过这个变成了mut类型 , 因此 , 只需要按部就班的和part2一样 , 现将创建出来 , 多加一个mut即可 。然后按照编译器的要求添加相应的生命周期参数
pub struct MutIter<'a, T> {// 因为这里查到的Node不仅要用来显示 , 而且还可以外部修改 , 因此把原来的Option