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

vfh0ocws  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(115)

下面的代码有两个几乎相同的函数。其中一个不编译。

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>`

这是怎么回事

ccrfmcuu

ccrfmcuu1#

你的非工作版本相当于这样:

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

现在的问题是,临时current_node.borrow()直到语句结束时才被删除。但当时current_node已经被替换了。
工作示例可以工作,因为它将临时变量存储在一个块范围内的变量中,该变量在从块返回之前被删除,因此也在重新分配current_node之前,所以一切顺利。

相关问题