簡體   English   中英

引用應該比閉包參數長

[英]Reference should outlive closure parameter

所以我有以下結構

struct Item;

#[derive(Default)]
struct Resource<'a> {
    _marker: std::marker::PhantomData<&'a ()>,
}

impl<'a> Resource<'a> {
    // Note: item has to be borrowed for 'a
    fn do_nothing(&mut self, item: &'a Item) {
        let _ = item;
    }
}

struct Context<'a> {
    resource: Resource<'a>,
}

impl<'a> Context<'a> {
    fn new() -> Self {
        Self { resource: Resource::default() }
    }

    fn do_something(&mut self, item: &'a Item) {
        self.resource.do_nothing(item);
    }
}

以及以下使用這些結構的 function。

fn do_stuff<F>(callback: F)
where
    F: FnOnce(Context),
{
    let ctx = Context::new();
    (callback)(ctx);
}

當我嘗試以下列方式使用它時

fn main() {
    let item = Item;

    do_stuff(|mut ctx| {
        ctx.do_something(&item);
    });
}

它給出以下編譯器錯誤:

error[E0597]: `item` does not live long enough
  --> src/main.rs:40:27
   |
39 |     do_stuff(|mut ctx| {
   |              --------- value captured here
40 |         ctx.do_something(&item);
   |         ------------------^^^^-
   |         |                 |
   |         |                 borrowed value does not live long enough
   |         argument requires that `item` is borrowed for `'static`
41 |     });
42 | }
   | - `item` dropped here while still borrowed

但是,由於我對 rust 生命周期的了解有限,我不確定如何解決它。 Item 應該比ctx長壽,因為ctx的壽命與do_stuff (?) 一樣長。 有沒有辦法告訴編譯器item的壽命比ctx長?

在處理生命周期時,我強烈推薦的一件事是嘗試盡可能地去除生命周期省略的糖分。 這里的問題實際上發生在您對do_stuff的定義中:

fn do_stuff<F>(callback: F)
where
    F: FnOnce(Context),
{
    let ctx = Context::new();
    (callback)(ctx);
}

脫糖到:

fn do_stuff<F>(callback: F)
where
    F: FnOnce(Context<'static>),
{
    let ctx = Context::new();
    callback(ctx);
}

'static是導致錯誤的原因。 如果您使 function 在整個生命周期內通用'a ,錯誤就會消失:


fn do_stuff<'a, F>(callback: F)
where
    F: FnOnce(Context<'a>),
{
    let ctx = Context::new();
    callback(ctx);
}

操場

暫無
暫無

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

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