Hello,
I am attempting to build a doubly linked list in Rust (I know about the entirely too many linked lists book, but I want to try everything I can to fix errors I encounter before resorting to that book). I have been struggling with this for a while now, so I was wondering how do I return a reference to the data inside an Rc (or RefCell)?
These are the type definitions for my linked list:
use std::{
cell::RefCell,
rc::{Rc, Weak},
};
const INDEX_OUT_OF_BOUNDS: &str = "Error: index is out of bounds.";
type StrongListNode<T> = Option<Rc<RefCell<ListNode<T>>>>;
type WeakListNode<T> = Option<Weak<RefCell<ListNode<T>>>>;
pub struct LinkedList<T> {
head: StrongListNode<T>,
tail: StrongListNode<T>,
size: usize,
}
struct ListNode<T> {
data: T,
prev: WeakListNode<T>,
next: StrongListNode<T>,
}
And this is the implementation (currently, I am stuck on implementing the get method):
impl<T> LinkedList<T> {
pub fn new() -> Self {
LinkedList {
head: None,
tail: None,
size: 0,
}
}
pub fn get(&self, index: usize) -> Result<&T, &str> {
if index >= self.size {
return Err(INDEX_OUT_OF_BOUNDS);
}
let mut curr = Rc::clone(self.head.as_ref().unwrap());
for _ in 0..index {
let temp = curr;
curr = Rc::clone(temp.borrow().next.as_ref().unwrap());
}
Ok(&curr.borrow().data)
}
}
These are the compiler errors I get (one for Rc and one for RefCell I assume):
error[E0515]: cannot return value referencing local variable `curr`
--> src/lib.rs:43:9
|
43 | Ok(&curr.borrow().data)
| ^^^^-------------^^^^^^
| | |
| | `curr` is borrowed here
| returns a value referencing data owned by the current function
error[E0515]: cannot return value referencing temporary value
--> src/lib.rs:43:9
|
43 | Ok(&curr.borrow().data)
| ^^^^-------------^^^^^^
| | |
| | temporary value created here
| returns a value referencing data owned by the current function
I would greatly appreciate any help/response. I tried testing the reference behavior out with Option<Rc<ListNode<T>>>
instead of Option<Rc<RefCell<ListNode<T>>>>
, but when I tried to dereference the Rc, I got a cannot move error, which does not make sense because isn't Deref for Rc supposed to return a reference to the data inside the Rc?
pub fn get(&self, index: usize) -> Result<(), &str> {
if index >= self.size {
return Err(INDEX_OUT_OF_BOUNDS);
}
let mut curr = Rc::clone(self.head.as_ref().unwrap());
for _ in 0..index {
let temp = curr;
curr = Rc::clone(temp.next.as_ref().unwrap());
}
let hello = *curr;
Ok(())
}
error[E0507]: cannot move out of an `Rc`
--> src/lib.rs:43:21
|
43 | let hello = *curr;
| ^^^^^
| |
| move occurs because value has type `ListNode<T>`, which does not implement the `Copy` trait
| help: consider borrowing here: `&*curr`