如何使用在 main 中创建的变量调用需要“静态生命周期”的函数?
How do I call a function that requires a 'static lifetime with a variable created in main?
我定义了一个结构,它有一个定义静态生命周期的函数:
impl MyStruct {
pub fn doSomething(&'static self) {
// Some code goes here
}
}
我像这样从 main 消费它:
fn main() {
let obj = MyStruct {};
obj.doSomething();
}
它用于 doSomething
调用以在应用程序的生命周期内阻塞和执行。
我 运行 遇到了生命周期检查的问题,它声明它可能比 main
函数长寿,这对我来说很奇怪,因为一旦 main
完成了应用程序应该退出。
有办法实现吗?
创建具有 'static
生命周期的引用的 主要 方法是使变量 static
。静态变量是可以在编译时:
创建的变量
struct MyStruct;
impl MyStruct {
pub fn do_something(&'static self) {}
}
static OBJ: MyStruct = MyStruct;
fn main() {
OBJ.do_something();
}
随着 Rust 的持续求值故事的改进,这将更加常见,但它永远不允许在运行时进行配置。
一种不太常见的方法是故意泄漏内存,产生一个持续 "forever" 的引用。不鼓励这样做,因为内存泄漏不是一件好事:
fn main() {
let obj = Box::leak(Box::new(MyStruct));
obj.do_something();
}
也可以创建单例:
- How do I create a global, mutable singleton?
- How can you make a safe static singleton in Rust?
as once main
is complete the application should exit.
也许吧,但是编译器不会将 main
特别地用于生命周期目的。
hyper requires a static runtime when running the server and processing each request.
不,不是。它有一个 : '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。
另请参阅:
最简单的方法是使用 static
变量,但如果您需要在 main
函数中实际设置值,则需要不安全的代码:
static mut OBJ: MyStruct = MyStruct;
fn main() {
unsafe {
OBJ = MyStruct {};
OBJ.doSomething();
}
}
之后 unsafe
几乎可以用可变静态做任何事情。
更好的方法是让库 (lazy_static
) 处理不安全的代码。
use lazy_static::lazy_static;
fn main() {
lazy_static!{
static ref OBJ: MyStruct = MyStruct {};
}
OBJ.doSomething();
}
我定义了一个结构,它有一个定义静态生命周期的函数:
impl MyStruct {
pub fn doSomething(&'static self) {
// Some code goes here
}
}
我像这样从 main 消费它:
fn main() {
let obj = MyStruct {};
obj.doSomething();
}
它用于 doSomething
调用以在应用程序的生命周期内阻塞和执行。
我 运行 遇到了生命周期检查的问题,它声明它可能比 main
函数长寿,这对我来说很奇怪,因为一旦 main
完成了应用程序应该退出。
有办法实现吗?
创建具有 'static
生命周期的引用的 主要 方法是使变量 static
。静态变量是可以在编译时:
struct MyStruct;
impl MyStruct {
pub fn do_something(&'static self) {}
}
static OBJ: MyStruct = MyStruct;
fn main() {
OBJ.do_something();
}
随着 Rust 的持续求值故事的改进,这将更加常见,但它永远不允许在运行时进行配置。
一种不太常见的方法是故意泄漏内存,产生一个持续 "forever" 的引用。不鼓励这样做,因为内存泄漏不是一件好事:
fn main() {
let obj = Box::leak(Box::new(MyStruct));
obj.do_something();
}
也可以创建单例:
- How do I create a global, mutable singleton?
- How can you make a safe static singleton in Rust?
as once
main
is complete the application should exit.
也许吧,但是编译器不会将 main
特别地用于生命周期目的。
hyper requires a static runtime when running the server and processing each request.
不,不是。它有一个 : '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。
另请参阅:
最简单的方法是使用 static
变量,但如果您需要在 main
函数中实际设置值,则需要不安全的代码:
static mut OBJ: MyStruct = MyStruct;
fn main() {
unsafe {
OBJ = MyStruct {};
OBJ.doSomething();
}
}
之后 unsafe
几乎可以用可变静态做任何事情。
更好的方法是让库 (lazy_static
) 处理不安全的代码。
use lazy_static::lazy_static;
fn main() {
lazy_static!{
static ref OBJ: MyStruct = MyStruct {};
}
OBJ.doSomething();
}