Arc*_*Bug 2 reference ownership rust borrow-checker
我之前搜索过这个问题,比如this和this,但是按照第一个链接的解决方案并尝试将它们应用到我的代码中,rustc 似乎误解了我想要做的事情。
我想创建一个链表并为节点中间分配一些引用并打印它们的值。首先,我使它们可变,以便创建从 head ref 到 tail ref 的列表,然后我想将它们转换为不可变的,从 tail ref 到 head ref,这不会违反所有权规则。最后,我想访问一些不可变的引用(中点)来获取它们的值。
我的代码:(游乐场)
struct Node<T> {
val: T,
next: Option<Box<Node<T>>>,
}
impl<T> Node<T> {
fn new(val: T) -> Option<Box<Node<T>>> {
Some(Box::new(Node { val, next: None }))
}
}
fn main() {
let head = &mut Node::new(0);
let a = &mut head.as_mut().unwrap().next;
*a = Node::new(10);
let b = &mut a.as_mut().unwrap().next;
*b = Node::new(20);
let c = &mut b.as_mut().unwrap().next;
*c = Node::new(30);
let tail = &mut c.as_mut().unwrap().next;
*tail = Node::new(40);
// Trying to make these mutable reference immutable.
let tail = &*tail;
// reference 'c' is converted to immutable,
// so nothing borrows 'b' as mutable anymore
let c = &*c;
// Reports error anyway.
// error[E0502]: cannot borrow `*b` as immutable
// because it is also borrowed as mutable
// 16 | let c = &mut b.as_mut().unwrap().next;
// | ---------- mutable borrow occurs here
// Didn't I just convert c to immutable?
let b = &*b;
let a = &*a;
let head = &*head;
println!(
"a is {}, b is {}, c is {}",
a.as_ref().unwrap().val,
b.as_ref().unwrap().val,
c.as_ref().unwrap().val
);
}
Run Code Online (Sandbox Code Playgroud)
这里出了问题,rustc 仍然报告说我尝试将它们借用为不可变的,因为它们是由可变的 ref 借用的。但我之前已经将 ref 转换为不可变的。为什么?
有什么解决方案可以让我的程序按预期运行吗?
你不能。
您可以将可变引用转换为不可变引用,如链接的问题所示,但该对象仍将被可变地借用。
这对于Cell::from_mut()健全的 API 来说是必要的:它们将可变引用转换为不可变引用,并依赖对象继续可变借用。
如果需要,您可以next一成不变地重新跟踪指针:
let head = &*head;
let a = &head.as_ref().unwrap().next;
let b = &a.as_ref().unwrap().next;
let c = &b.as_ref().unwrap().next;
Run Code Online (Sandbox Code Playgroud)
游乐场。
但实际上,整个链表式编程并不真正适合 Rust。
| 归档时间: |
|
| 查看次数: |
384 次 |
| 最近记录: |