[英]Rust says the function parameter does not live enough, even though proper lifetime have been placed
對於背景上下文:我正在創建一個基於觀察者/訂閱者的全局事件系統(使用單個共享事件系統)。 我決定使用FnMut
作為我的回調閉包。 放置在臨時結構Data<'a>
的impl
中的生命周期'a
應該允許方法mut_func()
的callback
參數與整個Data
結構一樣長。 因為callback
參數使用F
泛型,它絕對受生命周期'a
約束。 但是錯誤仍然出現,指出callback
參數的壽命不夠長。
我最初使用Box<T>
作為dyn FnMut(u32)
容器,但Box<T>
要求回調是'static
(因為我將盒裝泛型轉換為盒特征對象),這在我的場景中是無法實現(為了可讀性)。 然后我嘗試使用Rc<RefCell<T>>
可悲的是它不支持特征對象。
另外,我使用泛型callback
的參數,因為我想要的功能有,而不必看到更高的可讀性Box<T>
包繞整個封閉,這將是無處不在的,因為這個事件系統將是我的我的計划的核心部分。 我將盡一切努力使“前端”更具可讀性和更清晰(除了顯着的性能影響)。
注意:這是我的示例程序。 如果需要,我可以發布實際的程序。
錯誤:
error[E0597]: `callback` does not live long enough
> | impl<'a> Data<'a> {
> | -- lifetime `'a` defined here
> | fn mut_func<F: FnMut(u32) -> () + 'a>(&mut self, mut callback: F) {
> | self.o.push(&mut callback as &mut dyn FnMut(u32) -> ());
> | ------------^^^^^^^^^^^^^------------------------------
> | | |
> | | borrowed value does not live long enough
> | argument requires that `callback` is borrowed for `'a`
> | }
> | - `callback` dropped here while still borrowed
例子:
use std::any::Any;
use std::mem;
use std::rc::Rc;
use std::cell::RefCell;
struct Event<'a> {
obs: Vec<&'a mut dyn FnMut(u32) -> ()>,
}
impl<'a> Event<'a> {
fn subscriber<F: FnMut(u32) -> () + 'a>(&mut self, mut callback: F) {
self.o.push(&mut callback as &mut dyn FnMut(u32) -> ());
}
}
fn main () {
let mut e = Event {obs: Vec::new()};
let x = 3;
e.subscriber(|n| {x+n;});
}
callback
參數使用F
泛型,它絕對受生命周期'a
約束。 但是錯誤仍然出現,指出callback
參數的壽命不夠長。
callback
存在的時間足夠長,但問題是您沒有存儲收到的callback
,而是將其存儲為轉換為 trait 對象( dyn
) 並且該 trait 對象的數據必須歸某物所有。
我最初使用
Box<T>
作為dyn FnMut(u32)
容器,但Box<T>
要求回調為'static
不,它沒有。 這編譯:
struct Event<'a> {
obs: Vec<Box<dyn FnMut(u32) -> () + 'a>>,
}
impl<'a> Event<'a> {
fn subscriber<F: FnMut(u32) -> () + 'a>(&mut self, callback: F) {
self.obs.push(Box::new(callback));
}
}
然后再進行一次更改,您的示例將編譯:在e
之前定義x
以便x
壽命比e
:
fn main() {
let x = 3;
let mut e = Event {obs: Vec::new()};
e.subscriber(|n| {x+n;});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.