如果我理解正确,在 Rust 中无法创建可变借用 over
我遇到了以下错误:
但是,如果我从代码行中删除引用(并更新
一切都很好。但我不明白为什么,因为在第16行调用的解引用
std::rc::Rc
,你必须使用 Cell
或 RefCell
。但无论如何,我不明白如何使用它们。例如,考虑这个简单的例子:use std::cell::RefCell;
struct X (i32);
impl X {
fn foo(&mut self) {
self.0 = 0;
}
}
fn main () {
let x = X(5);
let rcx = RefCell::new(&x);
let mut mutx: std::cell::RefMut<&X> = rcx.borrow_mut();
(*mutx).foo();
}
我遇到了以下错误:
16:5: 16:9 error: cannot borrow immutable local variable `mutx` as mutable
16 mutx.foo();
但是,如果我从代码行中删除引用(并更新
mutx
的类型):let rcx = RefCell::new(x);
一切都很好。但我不明白为什么,因为在第16行调用的解引用
RefMut::deref_mut() -> &mut T
应该在第一种情况下返回 &&mut T
,而在第二种情况下返回 &mut T
。但由于编译器应该根据需要应用许多 *
(如果我理解解引用强制转换的工作方式),所以 RefMut<X>::deref_mut()
和 RefMut<&X>::deref_mut()
之间没有区别。
编辑:
我错误地忘记在第15行写上 mut
,就像链接示例中正确地写的那样。所以现在是 let mut mutx...
。
mut
,但我没有更新帖子中的代码。无论如何(关于第一个问题),即使我使用RefCell :: new(x)
(不带引用),我也将一个不可变值存储在RefCell
中,但这不会生成任何错误。我在这里使用引用的原因是我的原始代码实际上有点复杂(您可以在此处检查:http://is.gd/XoROad) - Kill KRTfoo = bar
时,所包含的内存的所有权被转移。此转移可以是到可变位置,这可以给予传递可变访问权限。但是您不能使用引用来做到这一点,因为您无法从引用中移出,因此永远无法将引用数据移动到可变位置。 - VeedracRefCell
也有一些特殊之处,因为它允许打破可变性的传递性:一个不可变的RefCell
可以给你对其内容的可变访问权限。如果其内容是一个值,它可以给出&mut T
。但如果其内容是一个引用,它只能给出&mut &T
,这使您可以修改内部引用指向的位置,但不能修改内部引用所指向的值。 - Veedrac