So, in order to teach myself some Rust, I decided to create a simply hybrid datatype that I like, the ChainVec. It's a doubly linked list of vectors, useful if you need to resize vectors that could grow to vast scales. It uses linked list logic, but the lookup, search, and iterate characteristics are much faster because they grow O(n/alot). That's not really the point, though: The problem I ran into would occur in any doubly linked list.
Here's the problem... in C, when I make the new linked list node, I can just set its 'tail' to a pointer to the previous. I can toss pointers like candy in C, but in Rust, I don't know how to create new pointers yet. Here is what I tried... (look under fn push_head for the invalid line)
Note: In my implementation, the 'head' node to the chainvec is whichever you choose to point to, so there is no separate struct for the list head/tail.
use std::{cell::RefCell, rc::Rc};
#[allow(dead_code)]
struct ChainVec<T> {
item: Option<Vec<T>>,
head: Option<Rc<RefCell<ChainVec<T>>>>,
tail: Option<Rc<RefCell<ChainVec<T>>>>,
}
impl<T> ChainVec<T> {
fn new(prealloc: usize) -> Self {
let vector: Vec<T> = Vec::with_capacity(prealloc);
Self {
item: Some(vector),
head: None,
tail: None,
}
}
fn new_with_links(
prealloc: usize,
head: Option<Rc<RefCell<ChainVec<T>>>>,
tail: Option<Rc<RefCell<ChainVec<T>>>>,
) -> Self {
let vector: Vec<T> = Vec::with_capacity(prealloc);
Self {
item: Some(vector),
head: head,
tail: tail,
}
}
fn push_head(&mut self, prealloc: usize) {
self.head = Some(Rc::new(RefCell::new(ChainVec::new_with_links(
prealloc,
None,
Some(Rc::new(RefCell::new(self))),
))));
}
}
#[allow(unused_variables)]
fn main() {
let alef: ChainVec<u32> = ChainVec::new(100);
println!("Hello, world!");
}
Obviously I got lost when I tried to create a new pointer in push_head. I got:
error[E0308]: mismatched types
--> src/main.rs:36:39
|
36 | Some(Rc::new(RefCell::new(self))),
| ------------ ^^^^ expected struct `ChainVec`, found `&mut ChainVec<T>`
| |
| arguments to this function are incorrect
|
= note: expected struct `ChainVec<T>`
found mutable reference `&mut ChainVec<T>`
A dereference operator doesn't do anything here... and I'm not sure how to proceed.
How would I create an Rc<RefCell<_>> that references a struct that already exists?