Hello there, I want to have a reference inside a vector, but the borrow checker for obvious reasons gives errors. Firstly I've solved it by using index instead of ref like in snippet below:
pub struct RenderSystem {
current_pass_id: Option<usize>,
passes: Vec<Pass>,
}
pub fn query(&mut self, command: RenderCommand) {
assert!(self.current_pass_id.is_some(), "Can't query command without render pass");
let id = self.current_pass_id.unwrap();
self.passes[id].commands.push(command);
}
It works, but it looks not idiomatically for the rust. I could use lifetime for ref, but I don't want element to live while lives RenderSystem
, every frame vector passes
is being cleared, so lifetime is render
function scope, but add this element to pass I can before enter to render
function.
There is another solution I've come up with - use Rc
and RefCell
, but It looks pretty ugly and actually I think it's less idiomatic than the previous example:
pub struct RenderSystem {
current_pass: Option<Rc<RefCell<Pass>>>,
passes: Vec<Rc<RefCell<Pass>>>,
}
pub fn query(&mut self, command: RenderCommand) {
assert!(
self.current_pass.is_some(),
"Can't query command without render pass"
);
let pass = self.current_pass.as_ref().unwrap();
pass.borrow_mut().commands.push(command);
}
Actually, in my particular case I've solved this problem just by using the last element of the vector:
pub fn query(&mut self, command: RenderCommand) {
assert!(
!self.passes.is_empty(),
"Can't query command without render pass"
);
let current_pass = self.passes.last_mut().unwrap();
current_pass.commands.push(command);
}
So the problem has solved, but I still curious if there are any other solutions without RefCell
and vector index. Or maybe it’s actually okay to have an index that refers to the desired item.