这是我的代码;在
Ref::computed
中,我收到一个错误,F
和 U
必须是 'static
:
use std::cell::RefCell;
use std::rc::Rc;
trait Observer<T> {
fn update(&mut self, v: &T);
}
struct Computed<U, F> {
value: U,
callback: F,
}
impl<T, U, F> Observer<T> for Computed<U, F> where F: Fn(&T) -> U {
fn update(&mut self, v: &T) {}
}
struct Ref<T> {
value: T,
observers: Vec<Rc<RefCell<dyn Observer<T>>>>,
}
impl<T> Ref<T> {
fn computed<U, F>(&mut self, callback: F) -> Rc<RefCell<Computed<U, F>>>
where
F: Fn(&T) -> U,
{
let s = Rc::new(RefCell::new(Computed {
value: callback(&self.value),
callback,
}));
self.observers.push(s.clone());
s
}
}
error[E0310]: the parameter type `F` may not live long enough
--> src/lib.rs:34:29
|
34 | self.observers.push(s.clone());
| ^^^^^^^^^
| |
| the parameter type `F` must be valid for the static lifetime...
| ...so that the type `F` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
28 | F: Fn(&T) -> U + 'static,
| +++++++++
error[E0310]: the parameter type `U` may not live long enough
--> src/lib.rs:34:29
|
34 | self.observers.push(s.clone());
| ^^^^^^^^^
| |
| the parameter type `U` must be valid for the static lifetime...
| ...so that the type `U` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
26 | fn computed<U: 'static, F>(&mut self, callback: F) -> Rc<RefCell<Computed<U, F>>>
| +++++++++
如果我按照错误建议进行操作,那么一切都会成功。
我就是不明白为什么。既然智能ptr拥有
F
的所有权,为什么还需要声明生命周期呢?它必须是'static
?如果有人可以解释,我将不胜感激。
该错误与对
clone
的调用无关。相反,这是因为您试图将值存储在 self.observers
中。
当您说
dyn Trait
而不指定生命周期时,会添加隐式生命周期,在本例中为 'static
,因此就好像您写了 dyn Trait + 'static
。 因此,observers
的Ref
场的类型实际上是Vec<Rc<RefCell<dyn Observer<T> + 'static>>>
。 这就是编译器强制您添加 'static
约束的原因,以便您强制转换为 dyn Observer<T>
的类型满足隐式 'static
生命周期界限。
如果你想允许trait对象包含非静态生命周期,你必须这样注释它:
struct Ref<'a, T> {
value: T,
observers: Vec<Rc<RefCell<dyn Observer<T> + 'a>>>,
}
完成此操作后,您需要向
impl Ref
块添加适当的生命周期注释。 具体来说,在 Ref::computed
中,您必须添加边界来约束 F
和 U
的生存时间至少与 Ref
的生命周期参数一样长:
impl<'a, T> Ref<'a, T> {
fn computed<U, F>(&mut self, callback: F) -> Rc<RefCell<Computed<U, F>>>
where
F: Fn(&T) -> U + 'a,
U: 'a,
{
let s = Rc::new(RefCell::new(Computed {
value: callback(&self.value),
callback,
}));
self.observers.push(s.clone());
s
}
}
(游乐场)