Hey,
I am currently working on a library (rxRust to be precise) where I have to do insertion into graph-like structures, and am now running into the following problem:
To append a node to the graph, the following function is defined by the library:
fn actual_subscribe<O>(self, observer: O) -> Self::Unsub
where
O: Observer<Item = Self::Item, Err = Self::Err> + 'a;
I am now implementing this function for an operator with the following signature:
pub struct GroupObservable<Discr, Key, Item, Err> {
source: Rc<RefCell<GroupObserver2<Discr, Key, Item, Err>>>,
}
Due to the nature of the problem I am solving, I need to have multiple writers to the GroupObserver2
, which is implemented by the Rc<RefCell<>>
construct.
The GroupObservable
appends the following object to the graph:
struct GroupObserver<Item, Err> {
observer: Box<dyn Observer<Err = Err, Item = Item>>,
}
Since I only know the exact type of the following node at runtime, and the parent node is constructed before the child node, the only solution I could come up with was boxing the node as a trait object.
To wrap it up, the implementation for GroupObservable
to append GroupObserver
to the graph is the following:
fn actual_subscribe<O>(self, observer: O) -> Self::Unsub
where
O: Observer<Item = Self::Item, Err = Self::Err> + 'a,
{
(*(self.source))
.borrow_mut()
.actual_subscribe(GroupObserver {
observer: Box::new(observer),
discr: self.discr,
key: self.key,
});
SingleSubscription::default()
}
When compiling this code, I receive the following error:
error[E0310]: the parameter type `O` may not live long enough
--> src/ops/group_by.rs:132:21
|
132 | observer: Box::new(observer),
| ^^^^^^^^^^^^^^^^^^ ...so that the type `O` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
127 | O: Observer<Item = Self::Item, Err = Self::Err> + 'a + 'static,
| +++++++++
For more information about this error, try `rustc --explain E0310`.
The proposed solution is not viable, as the constraints are given by the library.
I think I understand where the issue is coming from (observer
does not implement Clone
, so the value stays wherever it is now, and Box
just creates a pointer to it, resulting in not being able to control its lifetime), but is there really no option to move the ownership of a trait object to a struct in Rust?