上一章写了最小的链表,但有不足和需要改进的地方
- 避免重复发明轮子:使用 Option
- 让链表可用于任何元素类型:泛型
- 添加 peek 方法:生命周期
-
1 Option
enum Link{Empty,More(Box<Node>)}// 等价于type Link = Option<Box<Node>>
上一节的
Link实际上就是Option<Box<Node>>- 可以用类型别名来将
Link改成Option - 将上一节的
first.rs复制成second.rs,然后:type Link = Option<Box<Node>>- 字符串替换:
Link::More—>Link::Some - 字符串替换:
Link::Empty—>Link::None2 Option::take():取走值,留下None```rust
pub fn push(&mut self, val: i32) { let node = Node { elem: val, //next: mem::replace(&mut self.head, Link::None), next: self.head.take(), }; self.head = Link::Some(Box::new(node)); }
pub fn pop(&mut self) -> Option
fn drop(&mut self) { //let mut cur_link = mem::replace(&mut self.head, Link::None); let mut cur_link = self.head.take(); while let Link::Some(mut boxed_node) = cur_link { //cur_link = mem::replace(&mut boxed_node.next, Link::None); cur_link = boxed_node.next.take(); } }
<a name="SmGLC"></a># 3 Option::map():映射成另一种Option```rustpub fn pop(&mut self) -> Option<i32> {// 两种写法都可以// match mem::replace(&mut self.head, Link::None) {/*match self.head.take() {Link::None => None,Link::Some(ref mut node) => {mem::swap(&mut self.head, &mut node.next);Some(node.elem)}// 两种写法都可以Link::Some(node) => {self.head = node.next;Some(node.elem)}}*/// 使用 Option::map()// 注意: map() 要求所有权;node 的类型是 Box<Node>self.head.take().map(|node| {self.head = node.next;node.elem})}
