Hey all,
For separating the creation of the task (lazily) and the execution, I run into this problem:
if an enum can either borrow or own a value. How to change a borrowed to an onwed value for that enum WITH decoupling from the original value?
See my try below, but it doesnt work since the compiler still recognizes the test_enum
to contain the borrowed reference to the original_input
: "cannot move out of original_input
because it is borrowed"
///Struct that does not implement the Copy trait
#[derive(Clone)]
struct TestStruct {
value: i32,
}
/// Enum that can either borrow or Own a Test STruct
enum TestEnum<'a> {
Borrow { borrowed: &'a TestStruct },
Own { owned: TestStruct },
}
impl TestEnum<'_> {
/// Convert borrowed to owned values
fn change_borrowed_to_owned(&mut self) {
if let TestEnum::Borrow { borrowed: t } = self {
*self = TestEnum::Own {
//owned: t.clone(), //does not work, still complains about the lifetime
owned: t.to_owned(), //does not work, still complains about the lifetime
//owned: t.clone_into(), //does not make sense -> still need the original
};
} else {
panic!("TestEnum already has Ownership")
}
}
/// Convert borrowed to owned values
fn change_borrowed_to_owned_v2(&mut self) -> Self {
if let TestEnum::Borrow { borrowed: t } = self {
return TestEnum::Own {
owned: t.clone(), //does not work, still complains about the lifetime
//owned: t.to_owned(), //does not work, still complains about the lifetime
//owned: t.clone_into(), //does not make sense -> still need the original
};
} else {
panic!("TestEnum already has Ownership")
}
}
///test output
fn print(self) {
match self {
TestEnum::Own { owned: t } => println!("Owned value: {}", t.value),
TestEnum::Borrow { borrowed: t } => println!("Borrowed value: {}", t.value),
}
}
}
How to convert the borrowed value to owned values?
both tries of either modifying the test_enum
in-place or returning a new test_enum
will have the same lifetime as before and the compiler will complain.
// Input
let original_input = TestStruct { value: 2 };
let mut test_enum: TestEnum;
{
// assign a value to the enum
test_enum = TestEnum::Borrow {
borrowed: &original_input,
};
//convert to enum with ownership
test_enum.change_borrowed_to_owned();
//test_enum = test_enum.change_borrowed_to_owned_v2();
}
// move the original input
let moved_input = original_input;
test_enum.print()
Is there a way to make the compiler understand that there is no borrow anymore?
Sidenotes:
- This is just a toy-problem of what I actually want to achieve
- In the actual Code, the TestEnum is embedded inside another enum