英文:
Rust : drop(&RefMut) instead of drop(RefMut)?
问题
我知道当从 RefCell
中借用一个值时,我可以手动丢弃它以结束这个借用。
然而,如果我使用对 RefMut
的引用而不是直接使用 RefMut
,似乎无法使用 drop 特性来结束这个借用。
那么,尝试丢弃 &RefMut
会发生什么?为什么在这个操作中 RefMut
不会被丢弃?如果引用的 RefMut
没有被丢弃,那么什么时候会被丢弃?
use std::cell::RefCell;
struct Data {
pub x: usize,
}
fn main() {
let c = RefCell::new(Data { x: 42 });
let b = &c.borrow_mut();
drop(b);
let mut d = c.borrow_mut();
d.x = 43;
println!("Hello, world!");
}
输出:
thread 'main' panicked at 'already borrowed: BorrowMutError', src/main.rs:11:19
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
英文:
I know when borrowing a value from a RefCell
, I can manually drop it to end this borrow.
However, if I use the reference to a RefMut
instead of directly using the RefMut
, the drop trait seems invalid to end this borrow.
So, what happend when trying to drop the &RefMut
? and why the RefMut
will not be dropped during this operation. If the referenced RefMut
is not dropped, when will it be dropped ?
use std::cell::RefCell;
struct Data {
pub x: usize,
}
fn main() {
let c = RefCell::new(Data { x: 42 });
let b = &c.borrow_mut();
drop(b);
let mut d = c.borrow_mut();
d.x = 43;
println!("Hello, world!");
}
output
thread 'main' panicked at 'already borrowed: BorrowMutError', src/main.rs:11:19
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
答案1
得分: 3
References 只有在它们引用的值在某处也存在时才能存在。在 C/C++ 中,如果创建一个指向临时变量的引用但未将其存储在变量中,这将是未定义的行为。然而,在 Rust 中,这是合法的,会在后台创建一个不可见的变量,其生存周期延续至当前作用域的结束。这被称为临时生命周期扩展。更多信息可以在这里找到。
你可以通过引入另一个作用域来限制它的生命周期:
use std::cell::RefCell;
struct Data {
pub x: usize,
}
fn main() {
let c = RefCell::new(Data { x: 42 });
{
let b = &c.borrow_mut();
drop(b);
}
let mut d = c.borrow_mut();
d.x = 43;
println!("Hello, world!");
}
或者将它存储在一个命名变量中来限制它的生命周期:
use std::cell::RefCell;
struct Data {
pub x: usize,
}
fn main() {
let c = RefCell::new(Data { x: 42 });
let b_val = c.borrow_mut();
let b = &b_val;
drop(b);
drop(b_val);
let mut d = c.borrow_mut();
d.x = 43;
println!("Hello, world!");
}
英文:
References can only exist if the value they reference also exists somewhere. In C/C++ it would be undefined behaviour to create a reference to a temporary that doesn't get stored in a variable. In Rust, however, it is legal, and an invisible variable gets created in the background that lives until the end of the current scope. This is called temporary lifetime extension. More info can be seen here.
You can limit its lifetime by introducing another scope:
use std::cell::RefCell;
struct Data {
pub x: usize,
}
fn main() {
let c = RefCell::new(Data { x: 42 });
{
let b = &c.borrow_mut();
drop(b);
}
let mut d = c.borrow_mut();
d.x = 43;
println!("Hello, world!");
}
Hello, world!
Or by storing it in a named variable instead:
use std::cell::RefCell;
struct Data {
pub x: usize,
}
fn main() {
let c = RefCell::new(Data { x: 42 });
let b_val = c.borrow_mut();
let b = &b_val;
drop(b);
drop(b_val);
let mut d = c.borrow_mut();
d.x = 43;
println!("Hello, world!");
}
Hello, world!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论