Hello,
probably this question was already asked, but I could not find the answer.
I have a linked list of Maps and I want to return to the caller a reference to the value, which is
stored in the Map. However, after many tries I still could not achieve this.
Of course the caller can extract it itself, but this makes the api very ugly.
If it is not possible to achieve with the current approach what other options do I have?
Use a similar implementation from the std lib of the linked list?
Because I need to store the Map in two places and I can guarantee that it cannot be borrowed mutably
twice.
The following code illustrate the problem of
error[E0515]: cannot return reference to temporary value
--> src/main.rs:44:26
|
44 | .map(|entry| entry.get_entry().get(key))
| -----------------^^^^^^^^^
| |
| returns a reference to data owned by the current function
| temporary value created here
and the playground list is here. I also guess that the commented get
cannot work as well.
use std::cell::{Ref, RefCell, RefMut};
use std::collections::BTreeMap;
use std::ops::DerefMut;
use std::rc::Rc;
#[derive(Debug, PartialEq)]
pub struct Env<K, V> {
curr: Option<Rc<RefCell<Node<K, V>>>>,
}
#[derive(Debug, PartialEq)]
pub struct Node<K, V> {
prev: Option<Rc<RefCell<Node<K, V>>>>,
table: BTreeMap<K, V>,
}
pub struct TableRef<K, V> {
entry: Rc<RefCell<Node<K, V>>>,
}
impl<K: std::cmp::Ord, V> TableRef<K, V> {
pub fn get_entry(&self) -> Ref<'_, BTreeMap<K, V>> {
Ref::map((*self.entry).borrow(), |node| &node.table)
}
pub fn get_mut_entry(&self) -> impl DerefMut<Target = BTreeMap<K, V>> + '_ {
RefMut::map((*self.entry).borrow_mut(), |node| &mut node.table)
}
// pub fn get(&self, key: &K) -> Ref<Option<&V>> {
// let table = self.get_entry();
// Ref::map(table, |table| &table.get(key))
// }
}
impl<K: Ord, V> Env<K, V> {
pub fn new() -> Env<K, V> {
Env { curr: None }
}
pub fn get(&self, key: &K) -> Option<&V> {
self.iter()
.find(|env| env.get_entry().contains_key(key))
.map(|entry| entry.get_entry().get(key))
.flatten()
}
pub fn iter(&self) -> Iter<K, V> {
Iter {
curr: self.curr.as_ref().map(|node| node.clone()),
}
}
}
pub struct Iter<K, V> {
curr: Option<Rc<RefCell<Node<K, V>>>>,
}
impl<K, V> Iterator for Iter<K, V> {
type Item = TableRef<K, V>;
fn next(&mut self) -> Option<Self::Item> {
self.curr.take().map(|node| {
self.curr = (*node).borrow().prev.clone();
TableRef { entry: node }
})
}
}
fn main() {
println!("Hello, world!");
}