I have a struct and an implementation of this struct.
one of the members of the struct is a stdout_writer it's Rc<Option<RefCell<SomeNonCopyableStruct>>>
In one of the functions let's call it write I need to perform the following:
while self.writer.as_ref().unwrap().as_ref().borrow_mut().status().is_somethig() {
// The while performs an immutable borrow of self.
if self.execution().is_done() == 0 { // mutable borrow of self
///do something
}
}
My issue is that on the one hand, I need to do the while, which makes the immutable borrow to self, on the other hand, I need to do the execution which needs a mutable borrow.
So I'm quite stuck here since.
Is there a design pattern to handle such a situation?
The main issue I get with this code – assuming what you’re saying is that writer: Rc<Option<_>> – is that .is_ref() calls <Rc<…> as AsRef<_>>::as_ref not Option::as_ref. But that can be fixed in various ways, e.g.
while Option::as_ref(&self.writer).unwrap().borrow_mut().status().is_somethig()
{
// The while performs an immutable borrow of self.
if self.execution().is_done() == 0 { // mutable borrow of self
// do something
}
}
Really, it’s impossible to help here any further. The questions lacks all necessary detail. The types aren’t properly explained, the error you’re getting isn’t properly shown, I’m not even entirely sure if we are talking about the issue being a compilation error in the first place.
Remember, if you’re having issue resolving a compilation error, share the compilation error. Also share a full code example that reproduces the problem, if that isn’t too difficult.
So I managed to make this compile, but It's not very clear to me why is this working.
This is the original structure: Rc<Option<RefCell<BufferedWriter>>>
The code that works is
The original error was cannot move out of a shared reference value moved due to this call pointing to the unwrap
So why is the second as_ref() solves this issue?
Calling “as_ref” twice also resolves the issue, because Rc<T>: AsRef<T> (is in the prelude and) has a method called as_ref, too, which takes &Rc<T> and produces &T, so that’s giving us &Option<RefCell<BufferedWriter>> in the first step; and then that type has .as_ref() resolve to the Option::as_ref method instead, which is the one we actually wanted which takes &Option<RefCell<BufferedWriter>> and produces Option<&RefCell<BufferedWriter>>, which can support calling unwrap.
To make it more readable I would break it up into multiple assignment statements, with declared types if the types aren't clear, rather than a long chain of method calls.
Adding a comment with the info from Steffahn is the only way I know to clarify this.