I am having a hard time converting my standalone merge_sort
function into a trait for Vec<T>
. It seems I am running into lifetime errors with the way the merge sort algorithm works.
I have tried specifying the lifetimes in the function and trait declarations but it still is giving me a similar error.
My research on lifetimes includes...
- Effective Rust
- The Rust book
- Several YouTube videos on lifetimes
- Most questions on Stack Overflow regarding lifetimes
Here is the code
trait MergeSortable<T> {
fn merge_sort(&mut self);
fn _merge(&self, left: &mut Vec<T>, right: &mut Vec<T>) -> &mut Vec<T>;
}
impl<T: Ord + Clone + PartialEq> MergeSortable<T> for Vec<T> {
fn merge_sort(&mut self) {
if self.len() <= 1 {
return;
}
let mid = self.len() / 2;
let mut left = self[..mid].to_vec();
left.merge_sort();
let mut right = self[mid..].to_vec();
right.merge_sort();
self = self._merge(&mut left, &mut right);
}
fn _merge(&self, left: &mut Vec<T>, right: &mut Vec<T>) -> &mut Vec<T> {
if left.len() == 0 {
return right;
}
if right.len() == 0 {
return left;
}
if left[0] < right[0] {
let mut v: Vec<T> = Vec::new();
v.push(left[0].clone());
v.extend_from_slice(&self._merge(&mut left[1..].to_vec().clone(), &mut right.clone())[..]);
return &mut v;
}
let mut v: Vec<T> = Vec::new();
v.push(right[0].clone());
v.extend_from_slice(&self._merge(&mut left.clone(), &mut right[1..].to_vec().clone())[..]);
return &mut v;
}
}
And the errors:
error: lifetime of reference outlives lifetime of borrowed content... [E0312]
--> <anon>:27:20
|>
27 |> return left;
|> ^^^^
note: ...the reference is valid for the anonymous lifetime #1 defined on the block at 22:75...
--> <anon>:22:76
|>
22 |> fn _merge(&self, left: &mut Vec<T>, right: &mut Vec<T>) -> &mut Vec<T> {
|> ^
note: ...but the borrowed content is only valid for the anonymous lifetime #2 defined on the block at 22:75
--> <anon>:22:76
|>
22 |> fn _merge(&self, left: &mut Vec<T>, right: &mut Vec<T>) -> &mut Vec<T> {
|> ^
error: lifetime of reference outlives lifetime of borrowed content... [E0312]
--> <anon>:24:20
|>
24 |> return right;
|> ^^^^^
note: ...the reference is valid for the anonymous lifetime #1 defined on the block at 22:75...
--> <anon>:22:76
|>
22 |> fn _merge(&self, left: &mut Vec<T>, right: &mut Vec<T>) -> &mut Vec<T> {
|> ^
note: ...but the borrowed content is only valid for the anonymous lifetime #3 defined on the block at 22:75
--> <anon>:22:76
|>
22 |> fn _merge(&self, left: &mut Vec<T>, right: &mut Vec<T>) -> &mut Vec<T> {
|> ^
help: consider using an explicit lifetime parameter as shown: fn _merge<'a, 'b>(&'a self, left: &'a mut Vec<T>, right: &'b mut Vec<T>)
-> &mut Vec<T>
--> <anon>:22:5
|>
22 |> fn _merge(&self, left: &mut Vec<T>, right: &mut Vec<T>) -> &mut Vec<T> {
|> ^