Hi,
I am trying to use a FnMut on a struct whose behavior is only known at run-time, and I am struggling to make it work. I am not very familiar with the interior mutability yet, and I would kindly ask for some help.
The code below is a minimal example: at new
, the variable transposed
dictates what the method set
should do. The method set
is mutable and has a lifetime associated to the data
that is passed to the new
of A
.
type Set<'a> = Box<dyn FnMut(usize, usize) -> () + 'a>;
struct A<'a> {
data: Vec<Vec<usize>>,
set: Set<'a>,
}
impl<'a> A<'a> {
fn new(data: &'a [usize], transposed: bool) -> Self {
let mut inner = Vec::with_capacity(data.len());
let set: Set<'a> = if transposed {
Box::new(move |i, len| {
let a = &data[i..i+len];
inner.push(a.to_vec());
})
} else {
Box::new(move |i, len| {
let a = data[i..i+len].iter().map(|a| vec![*a]);
inner.extend(a);
})
};
Self {
data: inner,
set,
}
}
fn set(&mut self, i: usize, len: usize) {
(self.set)(i, len)
}
fn get(&self, i: usize, j: usize) -> usize {
self.data[i][j]
}
}
fn main() {
let data = vec![1, 2, 3];
let mut a = A::new(&data, true);
a.set(0, 1);
assert_eq!(a.get(0, 0), 1);
}
This code does not compile because inner
is was moved to the set
. However, it seems that there is not intrinsic limitation here (apart from the borrow checker).
Note that I am not interested in fixing the problem in the example above: I am interested in the idiom to solve these problems in Rust.
The gist that there is a boxed function inside a struct that mutates the struct. The function itself is not shared to outside that struct.