我需要在树中找到具有最大值的节点,假设子节点的值总是大于拥有节点的值,然后修改它:
error[E0499]: cannot borrow `node.nodes` as mutable more than once at a time
--> src/main.rs:13:19
|
12 | let mut max: Option<&mut Node> = Some(node);
| ---- first mutable borrow occurs here
13 | for n in &mut node.nodes {
| ^^^^^^^^^^ second mutable borrow occurs here
...
20 | }
| - first borrow ends here
借用检查器返回此错误:
mut
如果我从find_max
移除find_max
,它就会有效,但我看不出如何从find_max
返回可变引用。
重要的是#include <stdio.h>
void triangle(int size);
void triangle_aux(int size, int n);
int main()
{
int base_length;
printf("Enter the base length:\n");
scanf("%d",&base_length);
if(base_length < 1 || base_length > 79 || base_length%2 == 0)
printf("The maximum base length permitted is 79 and has to be an odd number.\nPlease try again with a valid number.\nThank You!!!");
else
triangle(base_length);
}
void triangle(int size) {
triangle_aux(size, 0);
}
void triangle_aux(int size, int n)
{
int i;
for(i=0; i<n; i++)
printf(" ");
if(n==size/2)
printf("*\n");
else {
for(i=n; i<size-n; i++)
printf("X");
printf("\n");
triangle_aux(size, n+1);
}
}
本身不会修改任何内容。它只是搜索一个合适的节点。
答案 0 :(得分:4)
不需要使用unsafe
:
fn find_max(node: &mut Node, val: usize) -> Option<&mut Node> {
if node.val < val {
return None;
}
if node.nodes.is_empty() {
return Some(node);
}
let mut max_val = node.val;
let mut max = None;
for n in &mut node.nodes {
if let Some(m) = find_max(n, max_val) {
max_val = m.val;
max = Some(m);
}
}
max
}
答案 1 :(得分:0)
似乎是unsafe
合理的罕见案例之一。
在这种情况下,通常的方法是用不可变引用替换可变引用并使用内部可变性。但是在这种情况下,我们需要递归地borrow()
RefCell
,并且即使在函数返回之后也以某种方式使它们保持活动状态。
考虑到问题不是由操作固有的不安全引起的,而是由于Rust借用检查器的限制,使用unsafe
是有意义的。请记住,虽然我有理由确定以下代码是安全的,但最好还是等待评论或其他解决方案。
fn find_max(node: &mut Node, val: usize) -> Option<&mut Node> {
if node.val < val {
return None;
}
let mut max = None;
let mut max_val = node.val;
// keep reference around as a pointer
let node_ptr = node as *mut Node;
// `{ node }` moves the reference instead of reborrowing it
// so we can recreate it later with no risk of undefined behavior
for n in &mut { node }.nodes {
if let Some(m) = find_max(n, max_val) {
max_val = m.val;
max = Some(m);
}
}
max.or_else(
// the closure is executed only when `max == None`
// and `node` was moved out earlier in `{node}`
// therefore there's no active mutable references reachable thru recreated reference
// function signature ensures that lifetime of the returned reference is ok
// thus we can safely recreate the same mutable reference we received in `node`
|| unsafe { node_ptr.as_mut() }
)
}
答案 2 :(得分:-2)
你可以用*代替&amp; mut来deref。但是[Node]
没有在编译时知道的常量大小