I'm learning Rust and thought I'd try to make a very simple reactive stream library. A sample of the code is below:
trait Observable<T> {
// some stuff for emitting values when requested
}
trait Mappable<T, U> {
fn map(self, f: fn(&T) -> U) -> Box<dyn Observable<U>>;
}
struct Just<T> {
value: T
}
impl<T> Observable<T> for Just<T> {}
impl<T, U: 'static> Mappable<T, U> for Just<T> {
fn map(self, f: fn(&T) -> U) -> Box<dyn Observable<U>> {
Box::new(Just { value: f(&self.value) })
}
}
In order to make it work, I need to give a 'static
lifetime to the U
type in the implementation of Mappable
for Just
. Without it, the compiler complains:
error[E0310]: the parameter type `U` may not live long enough
--> src/lib.rs:17:9
|
15 | impl<T, U> Mappable<T, U> for Just<T> {
| - help: consider adding an explicit lifetime bound `U: 'static`...
16 | fn map(self, f: fn(&T) -> U) -> Box<dyn Observable<U>> {
17 | / Box::new(Just {
18 | | value: f(&self.value),
19 | | })
| |__________^
|
note: ...so that the type `Just<U>` will meet its required lifetime bounds
--> src/lib.rs:17:9
|
17 | / Box::new(Just {
18 | | value: f(&self.value),
19 | | })
| |__________^
I don't understand why the compiler is complaining about this because the value is placed inside a Box
.
Providing the 'static
lifetime obviously works but I'm concerned that it would create a memory leak as intermediate stages in the stream would not be free'd until the program exits.
I think the solution is to make the lifetime of U
be the same as T
. But all my attempts at doing this have failed.
How can I express the above code without using 'static
?