任务很简单:从向量构造一个链表。链接列表应支持多线程。
我的第一次尝试是迭代向量,设置一个指向链表末尾的指针,在每个步骤中创建新节点并根据需要进行链接。然而 Rust 的借用检查器让它变得非常麻烦。
这是代码:
// dummy struct for simplicity
struct LinkedList {
next: Option<Arc<Mutex<LinkedList>>>,
val: u32,
}
fn main() {
let vec_int: Vec<u32> = vec![1, 2, 3, 4, 5];
let normal_res = LinkedList { next: None, val: 0 };
// head pointer
let mut head = Arc::new(Mutex::new(normal_res));
for (i, val) in vec_int.iter().enumerate() {
// the first one is different: fill in the created LinkedList
if i == 0 {
(*head).lock().unwrap().val = *val;
continue;
}
// create new LinkedList and link it
let next = LinkedList {
next: None,
val: *val,
};
(*head).lock().unwrap().next = Some(Arc::new(Mutex::new(next)));
// make head into the pointer to the proper child, but it will not work
// error: use of moved value
head = Arc::new(Mutex::new(next));
// error: can not assign to head because it is borrowed
head = (*head).lock().unwrap().next.as_ref().unwrap().clone();
// I have tried many more ways of manipulating the pointers, all failed
}
}
我的第二次尝试有效,但不是最佳选择,因为它必须反转向量。
fn main(){
let mut reversed = Arc::new(Mutex::new(LinkedList { next: None, val: 0 }));
for (i, val) in vec_int.iter().rev().enumerate() {
if i == 0 {
(*reversed).lock().unwrap().val = *val;
continue;
}
// assign the next
reversed = Arc::new(Mutex::new(LinkedList {
next: Some(reversed.clone()),
val: *val,
}));
}
}
我找到了同一主题的几个答案和教程,但他们的方法似乎不适用于
Arc<Mutex>
。
答案1:无法分配给变量,因为它是借用的
答案 2:从 Vec 创建 ListNode,并引用第一个节点
非常感谢任何帮助。
当您使用
Arc
时,大多数所有权问题都可以通过使用 Arc::clone(&)
来规避。
这是代码
fn main() {
let vec_int: Vec<u32> = vec![1, 2, 3, 4, 5];
let normal_res = LinkedList { next: None, val: 0 };
// head pointer
let mut head = Arc::new(Mutex::new(normal_res));
let normal_res = Arc::clone(&head);
for (i, val) in vec_int.iter().enumerate() {
// the first one is different: fill in the created LinkedList
if i == 0 {
(*head).lock().unwrap().val = *val;
continue;
}
// create new LinkedList and link it
let next = LinkedList {
next: None,
val: *val,
};
// use clone to circumvent ownership problem
let next = Arc::new(Mutex::new(next));
(*head).lock().unwrap().next = Some(Arc::clone(&next));
head = next;
}
}
如果你想循环遍历链表,方法如下:
let mut head = normal_res;
loop {
let dummy_head = Arc::clone(&head);
let dummy_head = dummy_head.lock().unwrap();
println!("val: {}", dummy_head.val);
if dummy_head.next.is_none(){
break;
}
head = Arc::clone(&dummy_head.next.as_ref().unwrap());
}