当尝试将双重链接列表包含在rust中时,我发现以下意外错误
if let Some(link) = self.tail.take() {
let x = link.borrow_mut();
link.borrow_mut().next = Some(node.clone());
} else { ... }
这里的链接被推断为Rc<RefCell<Node<..>>>
,编译器说:
不能借用不可变的局部变量
link
作为可变变量。
[尝试后,我想当use std::borrow::BorrowMut
时发生错误。
// compiles
fn test1() {
let a = Rc::new(RefCell::new(1));
let b = RefCell::new(1);
b.borrow_mut();
a.borrow_mut();
}
// doesn't compile
fn test2() {
use std::borrow::BorrowMut; // inserted this import!
let a = Rc::new(RefCell::new(1));
let b = RefCell::new(1);
b.borrow_mut();
a.borrow_mut();
}
此处test2()
无法编译。我想知道为什么这样工作。
您想要调用的是方法RefCell::borrow_mut()
。
但是,RefCell::borrow_mut()
是a
而不是Rc
,因此它没有RefCell
方法。这是自动解引用输入图片的地方。因为borrow_mut
实现了Rc<RefCell<T>>
特征,所以可以在方法调用时将其自动取消引用到Deref
,而这正是第一次测试中发生的情况。
现在,如果我们导入Deref
特征,则测试将停止工作。这是因为&RefCell<T>
特性还具有一种称为BorrowMut
的方法,即BorrowMut
:
borrow_mut
这意味着implemented for all types现在有impl<T: ?Sized> BorrowMut<T> for T { ... }
方法可用,因此没有Deref强制发生,并且我们的代码调用了错误的方法。