簡體   English   中英

Rust 說函數參數不夠活躍,即使已經設置了適當的生命周期

[英]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;});
}

Rust Playground 副本

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM