我以为我会通过改进一些非常简单的结构而潜入Rust。算法,我从一个链表开始。原来并不是那么简单。到目前为止,这是我的代码:
enum List<T>
{
Node(T, ~List<T>),
Nil
}
impl<T> List<T>
{
fn new(vector: &[T]) -> List<T> { Nil }
fn add(&mut self, item: T)
{
let tail = self;
loop
{
match *tail
{
Node(_, ~ref next) => tail = next,
Nil => break
}
}
*tail = Node(item, ~Nil);
}
}
这将无法编译,因为由于不兼容的可变性,下一个不能在match语句中分配给tail。我知道这可以很容易地使用垃圾收集指针来完成,但这种做法违背了练习的教育目的:我想知道如何在没有Gc或Rc指针的情况下做到这一点。
答案 0 :(得分:6)
看起来您正在尝试使用自己的列表来查找最终元素,但实际上并没有循环。假设您已经解决了这个问题,可以使用ref mut
代替ref
修复可变性问题。
为了自己尝试,我使用add()
的递归实现,这有效:
fn add(&mut self, item: T) {
match *self {
Node(_, ref mut next) => next.add(item),
Nil => *self = Node(item, ~Nil)
}
}
Offhand我不确定如何使用迭代方法实现这一点,因为可变借用的问题。
答案 1 :(得分:0)
迭代解决方案,使用Box::borrow_mut()
:
#[derive(Debug)]
enum List<T> {
Node(T, Box<List<T>>),
Nil
}
impl<T> List<T> {
fn new() -> List<T> { List::Nil }
fn add(&mut self, item: T) {
use std::borrow::BorrowMut;
let mut tail = self;
while let Self::Node(_, next) = tail {
tail = next.borrow_mut();
}
*tail = List::Node(item, Box::new(List::Nil));
}
}