The primary way to create a reference that has the 'static
lifetime is to make the variable static
. A static variable is one that can be created at compile time:
struct MyStruct;
impl MyStruct {
pub fn do_something(&'static self) {}
}
static OBJ: MyStruct = MyStruct;
fn main() {
OBJ.do_something();
}
As Rust's constant evaluation story improves, this will be more common, but it will never allow configuration at runtime.
A far less common method is to deliberately leak memory, producing a reference that will last "forever". This should be discouraged because leaking memory isn't a good thing:
fn main() {
let obj = Box::leak(Box::new(MyStruct));
obj.do_something();
}
There's also the possibility of creating a singleton:
as once main
is complete the application should exit.
Perhaps, but the compiler doesn't treat main
specially for lifetime purposes.
hyper requires a static runtime when running the server and processing each request.
No, it doesn't. It has a bound of : 'static
, which means that any references passed in must be 'static
, but you don't have to pass in a bare reference at all.
For patterns like this, the most common thing is to pass in something like an Arc
. This allows sharing of the underlying resource.
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());
}
You can even use interior mutability if you wanted dynamic reconfiguration.
See also:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…