如何为链表实现len()函数?

时间:2017-01-23 01:43:46

标签: rust

我实现了一些基本的链表操作:

use std::mem;

//Generic List
struct LinkedList<T> {
    head: Option<Box<Node<T>>>,
}
struct Node<T> {
    element: T,
    next: Option<Box<Node<T>>>,
}

//List functions
impl<T> LinkedList<T> {
    //Create empty list
    fn new() -> LinkedList<T> {
        LinkedList { head: None }
    }

    //push element
    fn push_back(&mut self, t: T) {
        let new_node = Box::new(Node {
            element: t,
            next: mem::replace(&mut self.head, None),
        });

        self.head = Some(new_node);

    }
}        

我无法实现len方法:

//length calculator
fn len(&self) -> usize {
    let ref mut list = self.head;
    let mut count = 0;

    while let &mut Some(ref rest) = list {
        count += 1;
        list = &mut rest.next;
    }
    count
}

我的想法是循环,而我可以确定我有一个Some,并在我的变量None中有list时停止。

虽然这不起作用,但我无法对非可变变量进行可变引用,显然我无法重新分配列表变量:

error: cannot borrow immutable field `self.head` as mutable
  --> 8_generics.rs:54:13
   |
54 |         let ref mut list = self.head;
   |             ^^^^^^^^^^^^

error: cannot borrow immutable field `rest.next` as mutable
  --> 8_generics.rs:59:25
   |
59 |             list = &mut rest.next;
   |                         ^^^^^^^^^

error[E0506]: cannot assign to `list` because it is borrowed
  --> 8_generics.rs:59:13
   |
 57|         while let &mut Some(ref rest) = list {
   |                             -------- borrow of `list` occurs here
58 |             count += 1;
59 |             list = &mut rest.next;
|             ^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `list` occurs     here

error[E0384]: re-assignment of immutable variable `list`
  --> 8_generics.rs:59:13
   |
54 |         let ref mut list = self.head;
   |             ------------ first assignment to `list`
...
59 |             list = &mut rest.next;
   |             ^^^^^^^^^^^^^^^^^^^^^ re-assignment of immutable variable

2 个答案:

答案 0 :(得分:3)

您似乎将可变变量绑定与可变引用混淆。我建议您阅读What's the difference in `mut` before a variable name and after the `:`?

简而言之,您不希望在此处对列表进行任何可变引用;你没有修改列表。您需要能够将包含不可变引用的变量变为列表的头部。

fn len(&self) -> usize {
    let mut list = &self.head;
    let mut count = 0;

    while let Some(ref rest) = *list {
        count += 1;
        list = &rest.next;
    }

    count
}

我还建议您阅读Learning Rust With Entirely Too Many Linked Lists

答案 1 :(得分:3)

使用可变局部变量(不是可变借位):

let mut list = &self.head;
while let Some(ref rest) = *list {
    count += 1;
    list = &rest.next;
}

这里我们需要绑定是可变的(let mut),而不是数据(&mut)。请参阅Mutability