Rust 使用可变引用覆盖变量时发生借用检查器错误
我有一个structRust 使用可变引用覆盖变量时发生借用检查器错误,rust,borrow-checker,Rust,Borrow Checker,我有一个structUI包含对Stdout的可变引用。我宁愿用一个全新的UI: 使用std::io::{stdout,Result,stdout,Write}; 结构用户界面{ fn新(标准输出:和的多标准输出)->结果{ 让ui=ui{ stdout:stdout, v:Box::新(()), }; Ok(用户界面) } fn写入(&mut self)->结果{ 写!(self.stdout,“heyyyy”)?; self.stdout.flush()?; 好(()) } } fn main
UI
包含对Stdout
的可变引用。我宁愿用一个全新的UI
:
使用std::io::{stdout,Result,stdout,Write};
结构用户界面{
fn新(标准输出:和的多标准输出)->结果{
让ui=ui{
stdout:stdout,
v:Box::新(()),
};
Ok(用户界面)
}
fn写入(&mut self)->结果{
写!(self.stdout,“heyyyy”)?;
self.stdout.flush()?;
好(())
}
}
fn main()->结果{
设mut stdout=stdout();
让mut ui=ui::new(&mut stdout)?;
ui=ui::新建(&mut stdout)?;
ui.write()?;//如果注释掉这一行,错误就会消失。
好(())
}
借用检查器抱怨标准输出被可变借用两次:
error[E0499]:不能一次多次将'stdout'作为可变项借用
-->src/main.rs:30:18
|
28 |让mut ui=ui::new(&mut stdout)?;
|--------第一个可变借用发生在此处
29 |
30 | ui=ui::新建(&mut stdout)?;
|-->^^^^^^^^^^^第二个可变借用发生在此处
| |
|当删除'ui'并运行'ui Result'类型的析构函数时,这里可以使用first-borrow{
设mut stdout=stdout();
让mut ui=ui::new(&mut stdout)?;
对于0..10中的uu{
下降(ui);
ui=ui::新建(&mut stdout)?;
ui.write()?;
}
好(())
}
error[E0499]:不能一次多次将'stdout'作为可变项借用
-->src/main.rs:33:22
|
28 |让mut ui=ui::new(&mut stdout)?;
|--------第一个可变借用发生在此处
...
33 | ui=ui::新建(&mut stdout)?;
|-->^^^^^^^^^^^第二个可变借用发生在此处
| |
|这里可以使用first borrow,当删除'ui'并在替换值时运行'ui类型的析构函数时,必须首先创建新值:
struct Noisy(u8);
impl Noisy {
fn new(v: u8) -> Self {
eprintln!("creating {}", v);
Self(v)
}
}
impl Drop for Noisy {
fn drop(&mut self) {
eprintln!("dropping {}", self.0);
}
}
fn main() {
let mut ui = Noisy::new(1);
ui = Noisy::new(2);
}
创建1
创建2
下降1
下降2
这意味着您的两个UI
结构将尝试共存。由于它们都有一个对stdout的可变引用
,Drop::Drop
实现可能会变异stdout
,这将违反引用规则,因为在一个点上会有多个活动的可变引用
当您不调用write
时,非词汇借用检查器会发现不需要借用,因此没有问题
那么为什么[在重新分配之前显式删除该值]会返回错误
因为那是
另见:
删除
,以便在销毁时可以解除分配其内容;因此,UI
会自动执行Drop
,这意味着在为新的UI
重新加载它和将它分配给UI
之间,执行的代码可以访问stdout
,可能是编译器意识到没有使用ui
,因此实际上没有执行赋值,但这只是一个猜测。take()
是一个很好的解决方案,但是请注意,该方法的一个更惯用的名称是into\u stdout()
-在将锈蚀为
的过程中,方法消耗自我
,并返回对象曾经拥有的内部事物的所有权。在这种情况下,您将返回原始的&mut stdout
(具有原始生存期),这允许您创建与原始用户“兼容”的新ui
。