Too-Many-Lists

1. A Bad Stack

引例

  • 用这种方式会有标签带来的额外开销,属于函数式编程语言的默认方法
  • 所以用下面的 C-like 结构体形式占用空间更小,
  • 而且单个节点能承载更多内容

#![allow(unused)]
fn main() {
#[derive(Debug)]
pub enum List<T> {
    Empty,
    Elem(T, Box<List<T>>),
}
}

完整案例


#![allow(unused)]
fn main() {
// 2.1. Layout
pub struct List {
    head: Link,
}
enum Link {
    Empty,
    More(Box<Node>),
}
struct Node {
    elem: i32,
    next: Link,
}
use std::mem;
impl List {
    // 2.2. New
    pub fn new() -> Self {
        List {
            head: Link::Empty,
        }
    }
    // 2.4. Push
    pub fn push(&mut self, elem: i32) {
        let new_node = Box::new(Node {
            elem,
            next: mem::replace(&mut self.head, Link::Empty),
        });
        self.head = Link::More(new_node)
    }
    // 2.5. Pop
    // 相比于上一个更常用而且更简洁的写法
    pub fn pop(&mut self) -> Option<i32> {
        match mem::replace(&mut self.head, Link::Empty) {
            Link::Empty => None,
            Link::More(node) => {
                self.head = node.next;
                Some(node.elem)
            }
        }
    }
}

// 2.6. Testing
#[cfg(test)]
mod test {
    #[test]
    fn basics() {
        // TODO
        use super::-;
        let mut list = List::new();

        // Check empty list behaves right
        assert_eq!(list.pop(), None);

        // Populate list
        list.push(1);
        list.push(2);
        list.push(3);

        // Check normal removal
        assert_eq!(list.pop(), Some(3));
        assert_eq!(list.pop(), Some(2));

        // Push some more just to make sure nothing's corrupted
        list.push(4);
        list.push(5);

        // Check normal removal
        assert_eq!(list.pop(), Some(5));
        assert_eq!(list.pop(), Some(4));

        // check exhaustion
        assert_eq!(list.pop(), Some(1));
        assert_eq!(list.pop(), None);

        // Check drop
        list.push(1);
        list.push(2);
        list.push(3);

    }
}
}

Drop 的手动编写

尝试根据尾递归写出 drop 函数,失败


#![allow(unused)]
fn main() {
// 2.7. Drop
impl Drop for List {
    fn drop(&mut self) {
        self.head.drop();
    }
}
impl Drop for Link {
    fn drop(&mut self) {
        match self {
            Link::Empty => {},
            Link::More(ref mut boxed_node) => {
                boxed_node.drop();
            }
        }
    }
}
impl Drop for Box<Node> {
    fn drop(&mut self) {
        self.ptr.drop();   // uh oh, not tail recursive!
        deallocate(self.ptr);
    }
}
impl Drop for Node {
    fn drop(&mut self) {
        self.next.drop();
    }
}
}

::: danger >We can't drop the contents of the Box after deallocating, so there's no way to drop in a tail-recursive manner! >Instead we're going to have to manually write an iterative drop for List that hoists nodes out of their boxes. ::: So, the next is the real way to write drop ourselfs


#![allow(unused)]
fn main() {
impl Drop for List {
    fn drop(&mut self) {
        println!("开始 drop");
        let mut cur_link = mem::replace(&mut self.head, Link::Empty);
        while let Link::More(mut boxed_node) = cur_link {
            println!("{}", boxed_node.elem);
            cur_link = mem::replace(&mut boxed_node.next, Link::Empty);
        }
    }
}
}

unimplemented!

::: warning


#![allow(unused)]
fn main() {
// 返回 unimplemented!()
impl List {
    pub fn pop(&mut self) -> Option<i32> {
        match &self.head {
            Link::Empty => {
                // TODO
            },
            Link::More(node) => {
                // TODO
            }
        }
        unimplemented!()
    }
}
}

:::

2. An Ok Singly-Linked Stack

优化目标

  1. 3.1: Option 简化语法
  • use Option to replace our own Enum
  • use Option.take() to replace mem::replace(&self, None)
  • use option.take().map(|elem {}|) to replace match option { None => None, Some(x) => Some(y) }
  1. 3.2 Generic 通用性
  • just use T to replace i32
  1. 3.3 Peek(偷看) 实现 peek
  • 注意 3 者的区别
  • self.head.take() -> self -> Option(T)
  • self.head.as_ref() -> &self -> Option(&T)
  • self.head.as_mut() -> &mut self -> Option(&mut T)
  1. 3.4 - 3.6 三种迭代器
  • IntoIter - T
  • IterMut - &mut T
  • Iter - &T

map(): Maps an Option<T> to Option<U> by applying a function to a contained value. as_ref()->&self: Converts from &Option<T> to Option<&T>. as_mut()->&mut self: Converts from &mut Option<T> to Option<&mut T>. take()->&mut self: Takes the value out of the option, leaving a [None] in its place

Option & Generic


#![allow(unused)]
fn main() {
use std::mem;

#[derive(Debug)]
pub struct List<T> {
    head: Link<T>,
}

type Link<T> = Option<Box<Node<T>>>;

#[derive(Debug)]
struct Node<T> {
    elem: T,
    next: Link<T>,
}

impl<T> List<T> {
    // 2.2. New
    pub fn new() -> Self {
        List { head: None }
    }
    // 2.4. Push
    pub fn push(&mut self, elem: T) {
        let new_node = Box::new(Node {
            elem,
            // next: mem::replace(&mut self.head, None),
            next: self.head.take(),
        });
        self.head = Some(new_node);
    }
    // 2.5. Pop
    pub fn pop(&mut self) -> Option<T> {
        self.head.take().map(|node| {
            self.head = node.next;
            node.elem  //  node.elem not need to be wrapped by Some()
        })
    }

}
}

Peek


#![allow(unused)]
fn main() {
impl<T> List<T> {
    /-
    impl<T> Option<T> {
        pub fn as_ref(&self) -> Option<&T>;
    }
    -/

    pub fn peek(&self) -> Option<&T> {

        // Converts from &Option<T> to Option<&T>.

        // self             -> &List
        // self.head        -> &Option< Box<Node<T>>>
        // self.head.as_ref ->  Option<&Box<Node<T>>>
        // map(node)        ->         &Box<Node<T>>
        // node.elem        ->                   T
        // &node.elem       ->         &         T
        // map->&node.elem  ->  Option<&         T  >
        self.head.as_ref().map(|node| {
            &node.elem
        })
    }
    pub fn peek_mut(&mut self) -> Option<&mut T> {
        // Converts from &mut Option<T> to Option<&mut T>.

        // self             -> &mut List
        // self.head        -> &mut Option<     Box<Node<T>>>
        // self.head.as_mut ->      Option<&mut Box<Node<T>>>
        // map(node)        ->             &mut Box<Node<T>>
        // node.elem        ->                           T
        // &mut node.elem   ->             &mut          T
        // map->&node.elem  ->      Option<&mut          T  >
        self.head.as_mut().map(|node| {
            &mut node.elem
        })
    }
    pub fn peek_(&mut self) -> Option<T> {
        // warning(not sure): mut_only_in_this_fu_but_only_read_after_read
        // Takes the value out of the option, leaving a [None] in its place

        // self             -> &mut List
        // self.head        -> &mut Option<     Box<Node<T>>>
        // self.head.take   ->      Option<&mut Box<Node<T>>>

        // self.head        -> &mut Option<None>
        // temp             -> &mut Option<     Box<Node<T>>>

        // map(node)        ->                  Box<Node<T>>
        // node.elem        ->                           T
        // map->node.elem   ->      Option<              T  >
        self.head.take().map(|node| {
            node.elem
        })
    }

}

#[test]
fn peek() {
    let mut list = List::new();
    assert_eq!(list.peek(), None);
    assert_eq!(list.peek_mut(), None);
    list.push(1); list.push(2); list.push(3);

    assert_eq!(list.peek(), Some(&3));
    assert_eq!(list.peek_mut(), Some(&mut 3));
    // match list.peek_mut() {
    //     Some(k) => {-k = 30},
    //     None => {}
    // }
    list.peek_mut().map(|val| {
        -val = 30;
    });
    assert_eq!(list.peek_mut(), Some(&mut 30));
    if let Some(val) = list.peek_mut() {
        println!("{}", val);
        -val = 10;
    }
    assert_eq!(list.peek_mut(), Some(&mut 10));
    assert_eq!(list.pop(), Some(10));
    assert_eq!(list.peek(), Some(&2));
    if let Some(val) = list.peek_() {
        println!("{}", val);
    }
}
}

IntoIter


#![allow(unused)]
fn main() {
// 3.4 IntoIter------------------------------------------------------------------------------

pub struct IntoIter<T>(List<T>);

impl<T> List<T> {
    pub fn into_iter(self) -> IntoIter<T> {
        IntoIter(self)
    }
}

impl<T> Iterator for IntoIter<T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.pop()
    }
}

#[test]
fn into_iter_test() {
    let mut list = List::new();
    list.push(1);
    list.push(2);
    list.push(3);
    let mut iter = list.into_iter();
    assert_eq!(iter.next(), Some(3));
    assert_eq!(iter.next(), Some(2));
}
}

Iter


#![allow(unused)]
fn main() {
// 3.5 Iter------------------------------------------------------------------------------
pub struct Iter<'a, T> {
    next: Option<&'a Node<T>>
}

impl<T> List<T> {
    // 1. initial
    // pub fn iter<'a>(&'a self) -> Iter<'a, T> {
    // 2. apply lifetime elision
    // pub fn iter(&self) -> Iter<T> {
    // 3. Or, if you're not comfortable "hiding" that a struct contains a lifetime, you can use the Rust 2018 "explicitly elided lifetime" syntax, '_:
    pub fn iter(&self) -> Iter<'_, T> {

        // self             -> &List                    | self                -> &List
        // self.head        -> &Option< Box<Node<T>>>   | self.head           -> &Option< Box<Node<T>>>
        // self.head.as_ref ->  Option<&Box<Node<T>>>   | self.head.as_deref  -> &Option<     Node<T> >
        // map(node)        ->         &Box<Node<T>>    |
        // -node            ->          Box<Node<T>>    |
        // --node           ->              Node<T>     |
        // &--node          ->             &Node<T>     |
        // map->node        ->  Option<    &Node<T> >   |

        // can be replaced by the next line
        Iter { next: self.head.as_ref().map(|node| { &--node }) }

        // Iter { next: self.head.as_deref() }

        // node: expected struct `second::Node`, found struct `std::boxed::Box`
        // -node: expected `&second::Node<T>`, found struct `std::boxed::Box`
        // --node: expected `&second::Node<T>`, found struct `second::Node`
    }
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<Self::Item> {

        // self                  -> &mut Iter                           | self                   -> &mut Iter
        // self.next             -> &mut Option<         &Node<T> >     | self.next              -> &mut Option<         &Node<T>>
        // map(node)             -> &mut                 &Node<T>       | map(node)              -> &mut                 &Node<T>
        //     node.next         -> &mut Option<         &Node<T> >     |     node.next          -> &mut Option<     Box< Node<T>>>
        //     node.next.as_ref  ->      Option<&mut Box< Node<T>>>     |     node.next.as_deref -> &mut Option<          Node<T> >
        //     map(inner_node)   ->             &mut Box< Node<T>>      |
        //     -inner_node       ->                  Box< Node<T>>      |
        //     --inner_node      ->                       Node<T>       |
        //     &--inner_node     ->                      &Node<T>       |
        //     map(inner_node)   ->      Option<         &Node<T> >     |
        // self.next             -> &mut Option<         &Node<T>>      | self.next              -> &mut Option<& Node<T>>
        // node.elem             -> &mut                       T        |
        // &node.elem            -> &mut                      &T        |
        // map->&node.elem       -> &mut Option<              &T >      |

        self.next.map(|node| {
            self.next = (-node).next.as_ref().map(|node| &--node);
            // self.next = node.next.as_deref();
            // self.next = node.next.as_ref().map::<&Node<T>, _>(|node| &node);
            // node.next = Some(Box::new(Node{elem: 1, next: None}));
            &node.elem
        })
    }
}

#[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));
}
}

3. A Persistent Stack

实现目标

list1 = A -> B -> C -> D
list2 = tail(list1) = B -> C -> D
list3 = push(list2, X) = X -> B -> C -> D

list1 -> A ---+
              |
              v
list2 ------> B -> C -> D
              ^
              |
list3 -> X ---+

Basic


#![allow(unused)]
fn main() {
use std::rc::Rc;
// basic -------------------------------------------------------------------
pub struct List<T> {
    head: Link<T>
}

type Link<T> = Option<Rc<Node<T>>>;

struct Node<T> {
    elem: T,
    next: Link<T>,
}

impl<T> List<T> {
    pub fn new() -> List<T> {
        List { head: None }
    }
    pub fn prepend(&self, elem: T) -> List<T> {
        List { head: Some(Rc::new(Node { elem, next: self.head.clone() })) }
    }
    pub fn tail(&self) -> List<T> {
        List { head: self.head.as_ref().and_then(|node| node.next.clone()) }
    }
    pub fn head(&self) -> Option<&T> {
        self.head.as_ref().map(|node| &node.elem)
    }
}
}

Iter


#![allow(unused)]
fn main() {
// Iter ------------------------------------------------------------------
pub struct Iter<'a, T> {
    next: Option<&'a Node<T>>
}
impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        self.next.map(|node| {
            self.next = node.next.as_ref().map(|node| &--node);
            &node.elem
        })
    }
}
impl<T> List<T> {
    pub fn iter(&self) -> Iter<T> {
        Iter { next: self.head.as_ref().map(|node| &--node) }
    }
}
}

Drop

多了判断 ref count 的过程


#![allow(unused)]
fn main() {
// drop ------------------------------------------------------------
impl<T> Drop for List<T> {
    fn drop(&mut self) {
        let mut head = self.head.take();
        while let Some(node) = head {
            if let Ok(mut node) = Rc::try_unwrap(node) {
                head = node.next.take();
            } else {
                break
            }
        }
    }
}
}

Test


#![allow(unused)]
fn main() {
#[cfg(Test)]
mod test {
    use super::List;
    #[test]
    fn basics_test() {
        let list = List::new();
        list.prepend(1).prepend(2).prepend(3);

        assert_eq!(list.head(), Some(&3));
        let list = list.tail();
        assert_eq!(list.head(), Some(&2));
        let list = list.tail();
        assert_eq!(list.head(), Some(&1));
        let list = list.tail();
        assert_eq!(list.head(), None);
        let list = list.tail();
        assert_eq!(list.head(), None);
    }
    #[test]
    fn iter_test() {
        let list = List::new().prepend(1).prepend(2).prepend(3);

        let mut iter = list.iter();
        assert_eq!(iter.next(), Some(&3));
        assert_eq!(iter.next(), Some(&2));
        assert_eq!(iter.next(), Some(&1));
    }

}
}

4. A Bad Safe Deque

加入了 Rc 和 RefCell

Layout


#![allow(unused)]
fn main() {
se std::rc::Rc;
use std::cell::{ Ref, RefMut, RefCell };

pub struct List<T> {
    head: Link<T>,
    tail: Link<T>,
}

type Link<T> = Option<Rc<RefCell<Node<T>>>>;

struct Node<T> {
    elem: T,
    next: Link<T>,
    prev: Link<T>,
}
}

Basic


#![allow(unused)]
fn main() {
impl<T> List<T> {
    pub fn new() -> List<T> {
        List { head: None, tail: None }
    }
    // 5.2 Building 下`
    pub fn push_front(&mut self, elem: T) {
        let new_head = Node::new(elem);
        match self.head.take() {
            Some(old_head) => {
                old_head.borrow_mut().prev = Some(new_head.clone());
                new_head.borrow_mut().next = Some(old_head);
                self.head = Some(new_head);
            },
            None => {
                self.head = Some(new_head.clone());
                self.tail = Some(new_head);
            }
        }
    }
    // 5.3 Breaking
    pub fn pop_front(&mut self) -> Option<T> {
        self.head.take().map(|old_head| {
            // 临时借用 old_head,并 take 了 next 的 ownership
            match old_head.borrow_mut().next.take() {
                Some(new_head) => {
                    new_head.borrow_mut().prev = None;
                    self.head = Some(new_head);
                }
                None => {
                    self.tail.take();
                }
            }
            Rc::try_unwrap(old_head).ok().unwrap().into_inner().elem
        })
    }
    // 5.4 Peeking
    // pub fn peek(&self) -> Option<&T> {
    //     self.head.as_ref().map(|node| {
    //         // Rc::try_unwrap(node).ok().unwrap().into_inner().elem
    //         // &node.borrow().elem
    //     })
    // }
    pub fn peek_front(&self) -> Option<Ref<T>> {
        self.head.as_ref().map(|node| {
            Ref::map(node.borrow(), |node| &node.elem)
        })
    }
    pub fn peek_front_mut(&mut self) -> Option<RefMut<T>> {
        self.head.as_ref().map(|node| {
            RefMut::map(node.borrow_mut(), |node| &mut node.elem)
        })
    }
    // Back ---------------------------------------------------------
    pub fn push_back(&mut self, elem: T) {
        let new_tail = Node::new(elem);
        match self.tail.take() {
            Some(old_tail) => {
                old_tail.borrow_mut().next = Some(new_tail.clone());
                new_tail.borrow_mut().prev = Some(old_tail.clone());
                self.tail = Some(new_tail);
            }
            None => {
                self.head = Some(new_tail.clone());
                self.tail = Some(new_tail);
            }
        }
    }
    pub fn pop_back(&mut self) -> Option<T> {
        self.tail.take().map(|old_tail| {
            match old_tail.borrow_mut().prev.take() {
                Some(new_tail) => {
                    new_tail.borrow_mut().next.take();
                    self.tail = Some(new_tail);
                }
                None => {
                    self.head = None;
                }
            }
            Rc::try_unwrap(old_tail).ok().unwrap().into_inner().elem
        })
    }
    pub fn peek_back(&self) -> Option<Ref<T>> {
        self.tail.as_ref().map(|node| {
            Ref::map(node.borrow(), |node| &node.elem)
        })
    }
    pub fn peek_back_mut(&mut self) -> Option<RefMut<T>> {
        self.tail.as_ref().map(|node| {
            RefMut::map(node.borrow_mut(), |node| &mut node.elem)
        })
    }
}

impl<T> Node<T> {
    pub fn new(elem: T) -> Rc<RefCell<Node<T>>> {
        Rc::new(RefCell::new(Node {
            elem,
            next:None,
            prev: None,
        }))
    }
}
}

Drop


#![allow(unused)]
fn main() {
impl<T> Drop for List<T> {
    fn drop(&mut self) {
        while self.pop_front().is_some() {}
    }
}
}

Iterator


#![allow(unused)]
fn main() {
// 另一个方向直接实现 DoubleEndedIterator Trait 就行
// IntoIter
pub struct IntoIter<T>(List<T>);

impl<T> List<T> {
    pub fn into_iter(self) -> IntoIter<T> {
        IntoIter(self)
    }
}

// natural
impl<T> Iterator for IntoIter<T> {
    type Item = T;
    fn next(&mut self) -> Option<T> {
        self.0.pop_front()
    }
}
// reverse
impl<T> DoubleEndedIterator for IntoIter<T> {
    fn next_back(&mut self) -> Option<T> {
        self.0.pop_back()
    }
}
}

Iter(danger)

:::warning

无法实现而且根本看不懂,一头雾水

:::


#![allow(unused)]
fn main() {
// Iter
pub struct Iter<'a, T>(Option<Ref<'a, Node<T>>>);

impl<T> List<T> {
    pub fn iter(&self) -> Iter<T> {
        Iter(self.head.as_ref().map(|head| {head.borrow()}))
        // 若为 Ref<T>
        // Iter(self.head.as_ref().map(|head| {Ref::map(head.borrow(), |head| &head.elem)}))
    }
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = Ref<'a, T>;
    fn next(&mut self) -> Option<Ref<'a, T>> {
        self.0.take().map(|node_ref| {
            // self.0 = node_ref.next.as_ref().map(|head| {head.borrow()});
            // // node_ref 在闭包内被借用
            // Ref::map(node_ref, |node| &node.elem)
            // // node_ref 在闭包外再次被借用
            let (next, elem) = Ref::map_split(node_ref, |node| {
                (&node.next, &node.elem)
            });
            self.0 = next.as_ref().map(|head| head.borrow());
            elem
        })
    }
}
}

5. An Unsafe Queue

5.1 Safe Rust

Well, pushing is actually fine.

push


#![allow(unused)]
fn main() {
// An Unsafe Queue

/-
input list:
[Some(ptr)] -> (A, Some(ptr)) -> (B, None)

flipped push X:
[Some(ptr)] -> (A, Some(ptr)) -> (B, Some(ptr)) -> (X, None)

-/

// Layout
pub struct List<'a, T> {
    head: Link<T>,
    tail: Option<&'a mut Node<T>>,
}

type Link<T> = Option<Box<Node<T>>>;

struct Node<T> {
    elem: T,
    next: Link<T>,
}

// Basic
impl<'a, T> List<'a, T> {
    pub fn new() -> List<'a, T> {
        List { head: None, tail: None }
    }

    pub fn push(&'a mut self, elem: T) {
        let new_tail = Box::new(Node {
            elem: elem,
            // When you push onto the tail, your next is always None
            next: None,
        });

        // Put the box in the right place, and then grab a reference to its Node
        match self.tail.take() {
            Some(old_tail) => {
                // If the old tail existed, update it to point to the new tail
                old_tail.next = Some(new_tail);
                self.tail = old_tail.next.as_deref_mut()
            }
            None => {
                // Otherwise, update the head to point to it
                self.head = Some(new_tail);
                self.tail = self.head.as_deref_mut()
            }
        };
    }
}
}

However pop is another story. If they're popping elements outside of our range, it should still be fine. We can't see those nodes so nothing will happen. However if they try to pop off the node we're pointing at... >everything will blow up! In particular when they go to unwrap the result of the try_unwrap, it will actually fail, and the whole program will panic.


#![allow(unused)]
fn main() {
pub fn pop(&mut self) -> Option<T> {
    self.head.take().map(|head| {
        let head = -head;
        self.head = head.next;
        if self.head.is_none() {
            self.tail = None;
        }
        head.elem
    })
}
}

5.2 Unsafe Rust

Layout

// Layout
pub struct List<T> {
    head: Link<T>,
    tail: -mut Node<T>,
}

type Link<T> = Option<Box<Node<T>>>;

struct Node<T> {
    elem: T,
    next: Link<T>,
}

use std::ptr;
impl<T> List<T> {
    pub fn new() -> Self {
        List { head: None, tail:  ptr::null_mut()}
    }
    pub fn push(&mut self, elem: T) {
        let mut new_tail = Box::new(Node {
            elem,
            next: None,
        });

        let raw_tail: -mut _ = &mut -new_tail;
        if !self.tail.is_null() {
            unsafe {
                (-self.tail).next = Some(new_tail);
            }
        } else {
            self.head = Some(new_tail);
        }
        self.tail = raw_tail;
    }
    pub fn pop(&mut self) -> Option<T> {
        self.head.take().map(|head| {
            let head = -head;
            self.head = head.next;
            if self.head.is_none() {
                self.tail = ptr::null_mut()
            };
            head.elem
        })
    }
}

Extras


#![allow(unused)]
fn main() {
pub struct IntoIter<T>(List<T>);

pub struct Iter<'a, T> {
    next: Option<&'a Node<T>>
}

pub struct IterMut<'a, T> {
    next: Option<&'a mut Node<T>>
}

impl<T> List<T> {
    pub fn peek(&self) -> Option<&T> {
        self.head.as_ref().map(|node| {
            &node.elem
        })
    }
    pub fn peek_mut(&mut self) -> Option<&mut T> {
        self.head.as_mut().map(|node| {
            &mut node.elem
        })
    }
    pub fn into_iter(self) -> IntoIter<T> {
        IntoIter(self)
    }
    pub fn iter(&self) -> Iter<T> {
        Iter { next: self.head.as_deref() }
    }
    pub fn iter_mut(&mut self) -> IterMut<T> {
        IterMut { next: self.head.as_deref_mut() }
    }
}

impl<T> Iterator for IntoIter<T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.pop()
    }
}
impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<Self::Item> {
        self.next.map(|node| {
            self.next = node.next.as_deref();
            &node.elem
        })
    }
}
impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<Self::Item> {
        self.next.take().map(|node| {
            self.next = node.next.as_deref_mut();
            &mut node.elem
        })
    }
}
}

test


#![allow(unused)]
fn main() {
mod test {
    use super::List;
    #[test]
    fn basics() {
        let mut list = List::new();

        // Check empty list behaves right
        assert_eq!(list.pop(), None);

        // Populate list
        list.push(1);
        list.push(2);
        list.push(3);

        // Check normal removal
        assert_eq!(list.pop(), Some(1));
        assert_eq!(list.pop(), Some(2));

        // Push some more just to make sure nothing's corrupted
        list.push(4);
        list.push(5);

        // Check normal removal
        assert_eq!(list.pop(), Some(3));
        assert_eq!(list.pop(), Some(4));

        // Check exhaustion
        assert_eq!(list.pop(), Some(5));
        assert_eq!(list.pop(), None);
    }
    #[test]
    fn into_iter() {
        let mut list = List::new();
        list.push(1); list.push(2); list.push(3);

        let mut iter = list.into_iter();
        assert_eq!(iter.next(), Some(1));
        assert_eq!(iter.next(), Some(2));
        assert_eq!(iter.next(), Some(3));
        assert_eq!(iter.next(), None);
    }

    #[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(&1));
        assert_eq!(iter.next(), Some(&2));
        assert_eq!(iter.next(), Some(&3));
        assert_eq!(iter.next(), None);
    }

    #[test]
    fn iter_mut() {
        let mut list = List::new();
        list.push(1); list.push(2); list.push(3);

        let mut iter = list.iter_mut();
        assert_eq!(iter.next(), Some(&mut 1));
        assert_eq!(iter.next(), Some(&mut 2));
        assert_eq!(iter.next(), Some(&mut 3));
        assert_eq!(iter.next(), None);
    }
}
}