I\'ve got a struct defined that has a function which defines a static lifetime:
impl MyStruct {
pub fn doSomething(&\'static self) {
// Some
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:
The naive way to do this is with a static
variable, but it will require unsafe code if you need to actually set the value inside your main
function:
static mut OBJ: MyStruct = MyStruct;
fn main() {
unsafe {
OBJ = MyStruct {};
OBJ.doSomething();
}
}
It's also unsafe
to do pretty much anything with a mutable static thereafter.
The much better way to do it is to let a library (lazy_static) take care of the unsafe code.
#[macro_use]
extern crate lazy_static;
fn main() {
lazy_static!{
static ref OBJ: MyStruct = MyStruct {};
}
OBJ.doSomething();
}