锈“借用......”编译错误

Rust "use of borrowed...." compilation error

提问人:wallgeek 提问时间:9/16/2023 最后编辑:Karmawallgeek 更新时间:9/25/2023 访问量:109

问:

我有一个节点列表

struct ListNode {
  val: i32,
  next: Option<Box<ListNode>>
}

impl ListNode {
  fn new(val: i32) -> Self {
    ListNode {
      next: None,
      val
    }
  }
}

然后我有一个遍历函数(此处的代码仅作为示例进行简化)。

fn traverse(mut list: Option<Box<ListNode>>) {
    let mut ptr = &mut list;
    let mut counter = 0;

    while counter < 5 {

        match ptr {
            None => {
                break;
            },
            Some(ptr_node) => { 
                if true {
                    ptr = &mut ptr_node.next;
                }
            }
        }

        counter += 1;
    }
}

当我编译此代码时,出现此编译错误

error[E0503]: cannot use `*ptr` because it was mutably borrowed
   |
   |         match ptr {
   |               ^^^
   |               |
   |               use of borrowed `ptr.0`
   |               borrow later used here
...
   |             Some(ptr_node) => { 
   |                  -------- borrow of `ptr.0` occurs here

error[E0499]: cannot borrow `ptr.0` as mutable more than once at a time
   |
   |             Some(ptr_node) => { 
   |                  ^^^^^^^^ `ptr.0` was mutably borrowed here in the previous iteration of the loop

error: aborting due to 2 previous errors; 2 warnings emitted

但是如果我将我的遍历函数更改为这个

fn traverse(mut list: Option<Box<ListNode>>) {
    let mut ptr = &mut list;
    let mut counter = 0;

    while counter < 5 {

        match ptr {
            None => {
                break;
            },
            Some(ptr_node) => { 
                ptr = &mut ptr_node.next;
            }
        }

        counter += 1;
    }
}

基本上,我从代码中删除了“if”语句。 这将成功编译。

谁能解释为什么“if”语句会导致编译错误?

rust borrow-checker 可变

评论

0赞 kmdreko 9/19/2023
这基本上是我自己问题的重复:为什么匹配的可变引用的条件赋值会导致借用错误?这归结为当前借用检查器的限制。
0赞 kmdreko 9/19/2023
悬赏,现有答案没有信誉的原因吗?或者您只是在寻找更多信息?
0赞 wallgeek 9/19/2023
只是在寻找有关此的更多信息。谢谢你的链接,将从该@kmdreko收集更多信息

答:

3赞 Finomnis 9/16/2023 #1

这很可能是当前借款检查器(“NLL”)中的误报。

当前的借款检查器存在一些已知的弱点。他们中的大多数将通过新的借用检查器“polonius”得到解决。可悲的是,它还没有发布,所以这样的情况发生了。

一个很好的迹象是,您的代码编译良好:

RUSTFLAGS="-Z polonius" cargo +nightly build

问题的解决方法基于具体情况,可以在此处找到更多信息。

但是,我不确定如何在您的特定情况下指导您,因为显而易见的建议是删除 .if true