无法分配,因为是临时借用的

问题描述 投票:0回答:1

我有以下代码,具有两个几乎相同的功能。其中之一无法编译。

struct Node {
    pub data: i32,
    pub next: Option<Rc<RefCell<Node>>>,
    pub prev: Option<Weak<RefCell<Node>>>
}

impl Node {
    pub fn new(data: i32) -> Rc<RefCell<Self>> {
        Rc::new(RefCell::new(Self {
            data,
            next: None,
            prev: None
        }))
    }
}


fn print_iterate_doesnt_work(node: &Rc<RefCell<Node>>) {
    let mut current_node = node.clone();
    loop {
        current_node = {
            let current_node_ref = current_node.borrow();
            print!("{} ", current_node_ref.data);
            if current_node_ref.next.is_none() { 
                return; 
            }

            // This line doesn't work
            current_node.borrow().next.as_ref().unwrap().clone() 
        }
    }
}

fn print_iterate_works(node: &Rc<RefCell<Node>>) {
    let mut current_node = node.clone();
    loop {
        current_node = {
            let current_node_ref = current_node.borrow();
            print!("{} ", current_node_ref.data);
            if current_node_ref.next.is_none() { 
                return; 
            }

            // This one works
            current_node_ref.next.as_ref().unwrap().clone()
        }
    }
}

据我了解,

current_node.borrow()
会创建临时的
Ref
。为什么编译器看不到我没有使用
current_node
和临时
Ref
。它说:

cannot assign to `current_node` because it is borrowed
the temporary is part of an expression at the end of a block;
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
borrow occurs due to deref coercion to `RefCell<Node>`rustcClick for full compiler diagnostic
main.rs(44, 13): `current_node` is borrowed here

main.rs(44, 13): a temporary with access to the borrow is created here ...

main.rs(46, 5): ... and the borrow might be used here, when that temporary is dropped 
and runs the destructor for type `Ref<'_, Node>`

rc.rs(1564, 5): deref defined here

main.rs(44, 13): for example, you could save the expression's value in a new local variable `x` 
and then make `x` be the expression at the end of the block: `let x = `, `; x`

其实我不太明白

... and the borrow might be used here, when that temporary is dropped  and runs the destructor for type 'Ref<'_, Node>' 

结果我不明白为什么我要

save the expression's value in a new local variable 'x'  and then make 'x' be the expression at the end of the block: 'let x = ', '; x'

货物检查:

error[E0506]: cannot assign to `current_node` because it is borrowed
    --> src\main.rs:39:9
     |
39   |         current_node = {
     |         ^^^^^^^^^^^^ `current_node` is assigned to here but it was already borrowed
...
45   |             current_node.borrow().next.as_ref().unwrap().clone() //
     |             ---------------------
     |             |
     |             `current_node` is borrowed here
     |             a temporary with access to the borrow is created here ...
46   |         }
47   |     }
     |     - ... and the borrow might be used here, when that temporary is dropped and runs the 
destructor for type `Ref<'_, Node>`
     |
     = note: the temporary is part of an expression at the end of a block;
             consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
     = note: borrow occurs due to deref coercion to `RefCell<Node>`

那么这是怎么回事?

rust ref borrow-checker
1个回答
0
投票

要解决这个问题并使

print_iterate_doesnt_work
编译,您可以按照编译器的建议引入一个新的局部变量来保存运算结果,然后将其分配给块末尾的
current_node

fn print_iterate_doesnt_work(node: &Rc<RefCell<Node>>) {
    let mut current_node = node.clone();
    loop {
        let new_current_node = {
            let current_node_ref = current_node.borrow();
            print!("{} ", current_node_ref.data);
            if current_node_ref.next.is_none() { 
                return; 
            }
            current_node_ref.next.as_ref().unwrap().clone()
        };
        current_node = new_current_node;
    }
}

这样,您可以确保在重新分配之前删除

current_node
的临时借用。

借用检查器对此代码感到满意,因为不存在重叠借用的可能性。

© www.soinside.com 2019 - 2024. All rights reserved.