【问题标题】:cannot use `*last_node` because it was mutably borrowed不能使用 `*last_node` 因为它是可变借用的
【发布时间】:2021-02-07 05:22:34
【问题描述】:

为什么会这样?

不能使用*last_node,因为它是可变借用的

#[derive(Debug)]
struct Node {
    data: i32,
    next: Link,
}

type Link = Option<Box<Node>>;

#[derive(Debug)]
struct List {
    size: i32,
    head: Link,
}

impl List {
    pub fn new() -> Self {
        List {
            size: 0,
            head: None,
        }
    }

    pub fn push(&mut self, data: i32) {
        let new_head = Box::new(Node {
            data: data,
            next: self.head.take(),
        });

        self.head = Some(new_head);
        self.size += 1;
    }

    pub fn append(&mut self, data: i32) {
        let new_node = Some(Box::new(Node {
            data: data,
            next: None,
        }));

        let mut last_node = &mut self.head;
        while let Some(node) = last_node {
            match node.next {
                None => break,
                Some(_) => last_node = &mut node.next,
            }
        }

        match last_node {
            None => self.head = new_node,
            Some(node) => node.next = new_node,
        }
        self.size += 1;
    }

    pub fn pop(&mut self) -> Option<i32> {
        let head = self.head.take();
        head.map(|node| {
            self.head = node.next;
            self.size -= 1;
            node.data
        })
    }
}

fn main() {
    let mut list = List::new();
    list.push(1);
    println!("{:?}", list);
    list.push(2);
    println!("{:?}", list);
    println!("{:?}", list.pop());
    list.push(3);
    println!("{:?}", list);
    list.push(4);
    println!("{:?}", list);
    list.append(5);
    println!("{:?}", list);
}

给出错误

error[E0503]: cannot use `*last_node` because it was mutably borrowed
  --> src/main.rs:48:13
   |
40 |         while let Some(node) = last_node {
   |                        ---- borrow of `last_node.0` occurs here
...
48 |             None => self.head = new_node,
   |             ^^^^
   |             |
   |             use of borrowed `last_node.0`
   |             borrow later used here

error[E0499]: cannot borrow `last_node.0` as mutable more than once at a time
  --> src/main.rs:49:18
   |
40 |         while let Some(node) = last_node {
   |                        ---- first mutable borrow occurs here
...
49 |             Some(node) => node.next = new_node,
   |                  ^^^^
   |                  |
   |                  second mutable borrow occurs here
   |                  first borrow later used here

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0499, E0503.
For more information about an error, try `rustc --explain E0499`.

但这不会给出错误:

pub fn append(&mut self, data: i32) {
        let new_node = Some(Box::new(Node {
            data: data,
            next: None,
        }));

        let mut last_node = &mut self.head;
        while let Some(node) = last_node {
            last_node = &mut node.next
            //match node.next {
            //    None => break,
            //    Some(_) => last_node = &mut node.next,
            //}
        }

        match last_node {
            None => self.head = new_node,
            Some(node) => node.next = new_node,
        }
        self.size += 1;
    }

【问题讨论】:

标签: rust


【解决方案1】:

借用检查器对条件可变重借很挑剔。不过,您的第二个没有错误的版本接近正确:

pub fn append(&mut self, data: i32) {
    let new_node = Some(Box::new(Node {
        data: data,
        next: None,
    }));

    let mut last_node = &mut self.head;
    while let Some(node) = last_node {
        last_node = &mut node.next;
    }

    *last_node = new_node;
    self.size += 1;
}

playground 上查看完整内容。

我认为原始的核心问题是,由于条件匹配,借用检查器认为 both last_nodelast_node.next 被同时借用,即使它们'实际上是同一个变量。有关此概念的更多信息,请参阅答案here

你写的没有缺陷,只是目前借用检查器没有接受。

【讨论】:

    猜你喜欢
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多