The task is simple: construct a linked list from a vector. The link list shall support multi-threading.
My first attempt is to iterate through the vector, set a pointer to the end of the linked list, create new node in each step and link as appropriate. Yet rust's borrow checker has made it very troublesome.
Here is the code:
// 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
}
}
My second attempt works, but is not optimal as it has to inverse the vector.
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,
}));
}
}
I found several answers and tutorials for the same topic, but their method does not seem to apply to Arc<Mutex>.
Answer 1 :Cannot assign to variable because it is borrowed
Answer 2 : create ListNode from Vec with ref to first Node
Any help is greatly appreciated.
Arc<Mutex<_>>is typically used when sharing things across threads. I don't see any threading mentioned here, so this is expensive and unnecessary. Mutability challenges here are better addressed using other tools (RefCell?)rev()does not reverse the vector in memory, it only walks it backwards. This is the most optimal you can get.