我已经定义了一个结构,它有一个定义静态生命周期的函数:
impl MyStruct {
pub fn doSomething(&'static self) {
// Some code goes here
}
}
我从主要消费它是这样的:
fn main() {
let obj = MyStruct {};
obj.doSomething();
}
它旨在doSomething
调用阻止并执行应用程序的生命周期。
我遇到了有关生命周期检查的问题,它说它可能比main
功能更长,这对我来说很奇怪,因为main
完成应用程序后应该退出。
有没有办法实现这个目标?
答案 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();
}