1 不正确的实现```rust
pub fn peek(&self) -> Option<&T> { self.head.map(|node| { &node.elem }) }
- `Option<T>`的`map`方法第一个参数为`self`,要求获取所有权,这是不允许的:不能通过共享引用`&self`取得`self.head`的所有权(不能移动`self.head`)
- 在作为`map`参数的闭包中,`node`是所有权类型,从闭包中返回所有权类型的引用是不允许的!
<a name="MFakj"></a>
# 2 使用Option::as_ref()```rust
impl<T> Option<T> {
pub fn as_ref(&self) -> Option<&T>;// Option<&Box<Node<T>>
}
pub fn peek(&self) -> Option<&T> {
self.head.as_ref().map(|node| {// node 的类型是 &Box<Node<T>>
&node.elem
})
}
3 使用Option::as_mut()```rust
impl
pub fn peek_mut(&mut self) -> Option<&mut T> { self.head.as_mut().map(|node| { &mut node.elem }) }
<a name="D2jHu"></a>
# 4 测试```rust
#[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));
list.peek_mut().map(|value| *value = 42);
assert_eq!(list.peek(), Some(&42));
assert_eq!(list.pop(), Some(42));
}
注意这一句: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
,是一个可变引用
- 写成