I'm trying quite complex stuff with Rust where I need the following attributes, and am fighting the compiler.
- Object which itself lives from start to finish of application, however, where internal maps/vectors could be modified during application lifetime
- Multiple references to object that can read internal maps/vectors of an object
- All single threaded
- Multiple nested iterators which are map/modified in lazy manner to perform fast and complex calculations (see example below)
A small example, which already causes problems:
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Weak;
pub struct Holder {
array_ref: Weak<RefCell<Vec<isize>>>,
}
impl Holder {
pub fn new(array_ref: Weak<RefCell<Vec<isize>>>) -> Self {
Self { array_ref }
}
fn get_iterator(&self) -> impl Iterator<Item = f64> + '_ {
self.array_ref
.upgrade()
.unwrap()
.borrow()
.iter()
.map(|value| *value as f64 * 2.0)
}
}
get_iterator
is just one of the implementations of a trait, but even this example already does not work.
The reason for Weak
/Rc
is to make sure that multiple places points to object (from point (1)) and other place can modify its internals (Vec<isize>
).
What is the best way to approach this situation, given that end goal is performance critical?
EDIT: Person suggested using https://doc.rust-lang.org/std/cell/struct.Ref.html#method.map
But unfortunately still can't get - if I should also change return type - or maybe the closure function is wrong here
fn get_iterator(&self) -> impl Iterator<Item=f64> + '_ {
let x = self.array_ref.upgrade().unwrap().borrow();
let map1 = Ref::map(x, |x| &x.iter());
let map2 = Ref::map(map1, |iter| &iter.map(|y| *y as f64 * 2.0));
map2
}
IDEA say it has wrong return type
the trait `Iterator` is not implemented for `Ref<'_, Map<std::slice::Iter<'_, isize>, [closure@src/bin/main.rs:30:46: 30:65]>>`