为什么这个编译失败?

时间:2021-01-26 00:09:08

标签: rust borrow-checker

我正在尝试获取对链表尾部的引用,这是我编写的代码:

pub struct ListNode {
    pub next: Option<Box<ListNode>>,
}

fn tail(mut head: &mut Option<Box<ListNode>>) -> &mut Option<Box<ListNode>> {
    while let Some(x) = head.as_mut() {
        head = &mut x.next;
    }
    head
}

这无法编译,因为它认为我将 head 借用为可变两次。我可以通过将其更改为以下内容来进行编译:

fn tail(mut head: &mut Option<Box<ListNode>>) -> &mut Option<Box<ListNode>> {
    while head.is_some() {
        head = &mut head.as_mut().unwrap().next;
    }
    head
}

在我看来,这两个函数做的事情完全一样,但第一个看起来更简洁。为什么不编译?有没有比我将其更改为更好的方法?

1 个答案:

答案 0 :(得分:1)

您已经拥有正确引用类型的值,因此不需要 as_mut

while let Some(x) = head {
    head = &mut x.next;
}
head

我不知道为什么你的第一个例子不能编译,因为我自己仍然不是说“借用检查器”的专家,但我的猜测是 Rust 只是保守并假设 {{1 }} 借用持续到变量 head.as_mut() 中,该变量被放入 x,因此是一个可变借用,持续时间与 head 一样长,而当我们像上面那样直接访问它时, Rust 足够聪明,可以理解真正发生的事情。

相关问题