首页 > 解决方案 > Moving structure containing reference into static closure doesn't work

问题描述

I'm creating a structure containing a reference and a function that gets a closure with 'static lifetime:

pub struct RefStruct<'a> {
    pub mref: &'a u32,
}

fn run<F>(mut f: F)
where
    F: FnMut() -> () + 'static,
{
    f();
}

I create an integer num which lives throughout the execution of main:

fn main() {
    let num = 32;
    ...
}

Now I want to create a struct referencing it. If I create it inside the 'static closure, it works fine:

fn main() {
    let num = 32;

    run(move || {
        let rstruct = RefStruct { mref: &num }; // Ok!
        print!("{}", rstruct.mref);
    });
}

However, if I create the struct in the main function scope and then move it into the closure it doesn't:

fn main() {
    let num = 32;
    let rstruct = RefStruct { mref: &num };

    run(move || {
        print!("{}", rstruct.mref);
    });
}

I get

error[E0597]: `num` does not live long enough
  --> src/main.rs:15:37
   |
15 |       let rstruct = RefStruct { mref: &num };
   |                                       ^^^^ borrowed value does not live long enough
16 | /     run(move || {
17 | |         print!("{}", rstruct.mref);
18 | |     });
   | |______- argument requires that `num` is borrowed for `'static`
19 |   }
   |   - `num` dropped here while still borrowed

error: aborting due to previous error

However, it seems to me that the two scopes should be identical.

标签: rustscopeclosureslifetimeborrow-checker

解决方案


基本上在第一种情况下,num在闭包中被引用,因此它被捕获并在闭包内移动。它变成'static并且引用是有效的。

在第二种情况下,num不被捕获,因为标识符从未在闭包中使用。因此,引用变为静态,而num不是。


推荐阅读