看书时,我正在尝试为“cons-list”类型添加方法,定义为
enum List<T> {
Item(T, Box<List<T>>),
Null,
}
我尝试实现的第一个方法是
from_slice
,它从 &[T]
构建一个缺点列表。
但是借用检查器不接受以下实现
impl<T> List<T> {
pub fn from_slice(v: &[T]) -> List<T>
where T: Copy
{
let n = v.len();
let lst = List::Null;
for i in (0..n).rev() {
let lst = List::Item(v[i], Box::new(lst));
}
lst
}
}
为什么这不被接受,我应该怎么做才能让借阅检查员相信这个程序是安全的?
有趣的是,扩展上面的
for
循环不会给出任何编译错误(借用检查器可能意识到前一个 lst
在每一行之后被遮蔽)。
// Expanding the previous function for v = [0, 1, 2]
let lst = List::Null;
let lst = List::Item(0, Box::new(lst));
let lst = List::Item(1, Box::new(lst));
let lst = List::Item(2, Box::new(lst));
通过在
let lst = ...
循环中执行 for
,您将创建一个新的 lst
绑定,该绑定会在该行之后立即删除。相反,您想要的是使 lst
上升一级 mut
并重新分配给它:
impl<T> List<T> {
pub fn from_slice(v: &[T]) -> List<T>
where
T: Copy,
{
let n = v.len();
let mut lst = List::Null;
for i in (0..n).rev() {
lst = List::Item(v[i], Box::new(lst));
}
lst
}
}