Peek
有一件事我们上次甚至没有去做,那就是 peek。我们开始吧,我们需要做的就是返回对列表头元素的引用(如果它存在的话)。听起来很简单,让我们试试:
pub fn peek(&self) -> Option<&T> {
self.head.map(|node| {
&node.elem
})
}> cargo build
error[E0515]: cannot return reference to local data `node.elem`
--> src/second.rs:37:13
|
37 | &node.elem
| ^^^^^^^^^^ returns a reference to data owned by the current function
error[E0507]: cannot move out of borrowed content
--> src/second.rs:36:9
|
36 | self.head.map(|node| {
| ^^^^^^^^^ cannot move out of borrowed content
叹。 Rust,现在怎么办?
map按值获取self,这会将Option从它所在的对象中移出。以前这是好的,因为我们刚刚把它拿出来,但现在我们真的想把它留在原来的地方。正确的处理方法是使用 Option 上的 as_ref 方法,它有以下定义:
它将 Option 降级为对其内部的引用。我们可以自己用一个显式的匹配来完成,但是不可以。这确实意味着我们需要做一个额外的解引用来切断额外的间接寻址,但谢天谢地,operator 为我们处理。
搞定了。
我们也可以使用 as_mut 创建一个可变的版本:
别忘了测试一下:
这很好,但是我们并没有真正的测试看看我们是否可以改变peek_mut的返回值,是吗?如果一个引用是可变的,但是没有人对它进行变异,那么我们真的测试过它的可变性吗?让我们试着在这个选项上使用map,在以下位置输入一个深刻的值:
编译器抱怨值是不可变的,但是我们很清楚地写下了&mut value;给出了什么?事实证明,以这种方式编写闭包的参数并没有指定值是可变引用。相反,它会创建一个模式,该模式将与闭包的参数相匹配;|&mut value |意味着“参数是一个可变的引用,但是请将它指向的值复制到value中”。如果我们只使用 |value |,那么值的类型将是&mut i32,我们实际上可以改变head:
好多了!
Last updated
Was this helpful?