1 不正确的实现```rust

pub fn peek(&self) -> Option<&T> { self.head.map(|node| { &node.elem }) }

  1. - `Option<T>``map`方法第一个参数为`self`,要求获取所有权,这是不允许的:不能通过共享引用`&self`取得`self.head`的所有权(不能移动`self.head`
  2. - 在作为`map`参数的闭包中,`node`是所有权类型,从闭包中返回所有权类型的引用是不允许的!
  3. <a name="MFakj"></a>
  4. # 2 使用Option::as_ref()```rust
  5. impl<T> Option<T> {
  6. pub fn as_ref(&self) -> Option<&T>;// Option<&Box<Node<T>>
  7. }
  8. pub fn peek(&self) -> Option<&T> {
  9. self.head.as_ref().map(|node| {// node 的类型是 &Box<Node<T>>
  10. &node.elem
  11. })
  12. }

3 使用Option::as_mut()```rust

impl Option { pub fn as_mut(&mut self) -> Option<&mut T>;// Option<&mut Box> }

pub fn peek_mut(&mut self) -> Option<&mut T> { self.head.as_mut().map(|node| { &mut node.elem }) }

  1. <a name="D2jHu"></a>
  2. # 4 测试```rust
  3. #[test]
  4. fn peek() {
  5. let mut list = List::new();
  6. assert_eq!(list.peek(), None);
  7. assert_eq!(list.peek_mut(), None);
  8. list.push(1);
  9. list.push(2);
  10. list.push(3);
  11. assert_eq!(list.peek(), Some(&3));
  12. assert_eq!(list.peek_mut(), Some(&mut 3));
  13. list.peek_mut().map(|value| *value = 42);
  14. assert_eq!(list.peek(), Some(&42));
  15. assert_eq!(list.pop(), Some(42));
  16. }

注意这一句:list.peek_mut().map(|value| *value = 42);,不能写成list.peek_mut().map(|&mut value| value = 42);

  • peek_mut()返回类型是Option<&mut i32>,则
    • 写成|&mut value|时,value对应i32(因为前面的&mut已经匹配了),是一个不可变变量
    • 写成|value|时,value对应&mut i32,是一个可变引用