I am implementing a linked list in Rust, and so far, the best way I have found to let the nodes point to other nodes or point to nothing is multiple structs that implement the same trait. (Option wouldn't work, because I couldn't figure out how to modify the item inside the Option without consuming the Option.) To make sure all nodes are owned, I have each node own the next node but have a reference to the previous node.
**Yeah, I know my method of accessing the SomeLLElement
fields by calling get_LL_element
and then unwrapping the Option is quite janky. If you can think of something better, please let me know.
struct EmptyLLElement;
struct SomeLLElement<'a, T> {
val: T,
next: Box<dyn LLElement<'a, T>>,
prev: &'a Box<dyn LLElement<'a, T>>,
}
fn LLEmpty() -> Box<EmptyLLElement> {
Box::new(EmptyLLElement)
}
trait LLElement<'a, T>{
fn get_LL_element(self) -> Option<SomeLLElement<'a, T>>;
}
impl <'a, T> LLElement<'a, T> for EmptyLLElement {
fn get_LL_element(self) -> Option<SomeLLElement<'a, T>> {
None
}
}
impl <'a, T> LLElement<'a, T> for SomeLLElement<'a, T> {
fn get_LL_element(self) -> Option<SomeLLElement<'a, T>> {
Some(self)
}
}
fn main(){
let myvar: Box<dyn LLElement<i32>> = Box::new(SomeLLElement{ val: 1, next: LLEmpty(), prev: &LLEmpty() });
let myvar2: SomeLLElement<i32> = match myvar.get_LL_element() {
Some(x) => x,
None => panic!("Empty!")
};
// println!("{}", myvar2.val);
}
The compiler is not allowing me to pass in the empty object (&LLEmpty()
) to SomeLLElement.prev
.
error[E0308]: mismatched types
--> src\main.rs:69:97
|
69 | let myvar: Box<dyn LLElement<i32>> = Box::new(SomeLLElement{ val: 1, next: LLEmpty(), prev: &LLEmpty() });
| ^^^^^^^^^^ expected trait object `dyn LLElement`, found struct `EmptyLLElement`
|
= note: expected reference `&Box<(dyn LLElement<'_, {integer}> + 'static)>`
found reference `&Box<EmptyLLElement>`
If I remove the ampersand from that line
let myvar: Box<dyn LLElement<i32>> = Box::new(SomeLLElement{ val: 1, next: LLEmpty(), prev: LLEmpty() });
and make prev an object instead of a reference,
prev: Box<dyn LLElement<'a, T>>,
--which is not what I want to do, but hey--the error goes away. The compiler should be able to see that EmptyLLElement
is an instance of dyn LLElement
, right? Shouldn't that also mean that &Box<EmptyLLElement>
is compatible for &Box<dyn LLElement>
?