上一章写了最小的链表,但有不足和需要改进的地方
- 避免重复发明轮子:使用 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::None
2 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```rust
pub 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
})
}