如何使用在main中创建的变量调用需要静态生命周期的函数?

时间:2018-06-07 11:58:03

标签: rust lifetime

我已经定义了一个结构,它有一个定义静态生命周期的函数:

impl MyStruct {
    pub fn doSomething(&'static self) {
        // Some code goes here
    }
}

我从主要消费它是这样的:

fn main() {
    let obj = MyStruct {};
    obj.doSomething();
}

它旨在doSomething调用阻止并执行应用程序的生命周期。

我遇到了有关生命周期检查的问题,它说它可能比main功能更长,这对我来说很奇怪,因为main完成应用程序后应该退出。

有没有办法实现这个目标?

2 个答案:

答案 0 :(得分:3)

创建具有'static生命周期的引用的主要方法是创建变量static。静态变量是可以在编译时创建的变量:

struct MyStruct;

impl MyStruct {
    pub fn do_something(&'static self) {}
}

static OBJ: MyStruct = MyStruct;

fn main() {
    OBJ.do_something();
}

随着Rust的常量评估故事的改进,这将更常见,但它永远不会允许在运行时进行配置。

一种不常见的方法是故意泄漏内存,产生一个持续“永远”的引用。这应该是不鼓励的,因为泄漏记忆不是一件好事:

fn main() {
    let obj = Box::leak(Box::new(MyStruct));
    obj.do_something();
}

还有可能创建一个单身人士:

  

一旦main完成,应用程序就应该退出。

也许,但编译器不会特意终止main

  运行服务器并处理每个请求时,

hyper需要静态运行时。

不,它没有。它的边界为: 'static,这意味着传入的任何引用都必须是'static,但您根本不需要传入一个裸引用。

对于这样的模式,最常见的是传递类似Arc的内容。这允许共享底层资源。

pub fn do_something<F, T>(f: F)
where
    F: Fn() -> T + 'static,
    T: 'static,
{
    // "spawn" 3 threads
    f();
    f();
    f();
}

struct MyStruct;

static OBJ: MyStruct = MyStruct;

fn main() {
    // OK
    do_something(|| &OBJ);

    // Not OK
    let another = MyStruct;
    do_something(|| &another);

    // OK
    use std::sync::Arc;
    let shared = Arc::new(MyStruct);
    do_something(move || shared.clone());
}

如果您想要动态重新配置,甚至可以使用interior mutability

另见:

答案 1 :(得分:3)

执行此操作的天真方法是使用static变量,但如果您需要在main函数中实际设置值,则需要使用不安全的代码:

static mut OBJ: MyStruct = MyStruct;

fn main() {
    unsafe {
        OBJ = MyStruct {};
        OBJ.doSomething();
    }
}

此后unsafe还可以使用可变静态做任何事情。

更好的方法是让库(lazy_static)处理不安全的代码。

#[macro_use]
extern crate lazy_static;

fn main() {
    lazy_static!{
        static ref OBJ: MyStruct = MyStruct {};
    }
    OBJ.doSomething();
}