Rust有一些保留的生命周期名称,其中之一是“ ’static ”。你可能在下面两种情况下使用它们:
// A reference with 'static lifetime:
let s: &'static str = "hello world";
// 'static as part of a trait bound:
fn generic<T>(x: T) where T: 'static {}
这两种用法有相关性,但是也有些许区别。对于初学者会感到一些困惑。下面有一些示例来介绍每一种的使用情景。
引用生命周期
使用’static作为引用的生命周期表明数据可以一直保留在整个程序运行期间。它也可以强制转为更短的生命周期。
有两种方法使某个变量设置成’static生命周期,它们都保存在程序的只读内存中:
- 使用带有static的常量声明
- 将某个字符串配置为’static str类型
下面的示例展示了这两种用法:
// Make a constant with `'static` lifetime.
static NUM: i32 = 18;
// Returns a reference to `NUM` where its `'static`
// lifetime is coerced to that of the input argument.
fn coerce_static<'a>(_: &'a i32) -> &'a i32 {
&NUM
}
fn main() {
{
// Make a `string` literal and print it:
let static_string = "I'm in read-only memory";
println!("static_string: {}", static_string);
// When `static_string` goes out of scope, the reference
// can no longer be used, but the data remains in the binary.
}
{
// Make an integer to use for `coerce_static`:
let lifetime_num = 9;
// Coerce `NUM` to lifetime of `lifetime_num`:
let coerced_static = coerce_static(&lifetime_num);
println!("coerced_static: {}", coerced_static);
}
println!("NUM: {} stays accessible!", NUM);
}
因为’static引用在程序剩余的生命周期中都需要可用,因此它们可以在程序执行时创建。为了演示作用,下面的示例使用Box::leak来动态创建’static引用。在这种情况下,它铁定不会在整个存续期间都有效,只会在泄漏点之后才会有效。
extern crate rand;
use rand::Fill;
fn random_vec() -> &'static [usize; 100] {
let mut rng = rand::thread_rng();
let mut boxed = Box::new([0; 100]);
boxed.try_fill(&mut rng).unwrap();
Box::leak(boxed)
}
fn main() {
let first: &'static [usize; 100] = random_vec();
let second: &'static [usize; 100] = random_vec();
assert_ne!(first, second)
}
Trait约束
作为trait约束,这意味着类型不会包含任何非静态的引用。即:接收器会保存这个类型和你想要的那么久,直到你销毁它们。
注意:任何已有所有权的数据总是可以传递’static生命周期的约束,但是对于有所有权数据的引用不是这样的:
use std::fmt::Debug;
fn print_it( input: impl Debug + 'static ) {
println!( "'static value passed in is: {:?}", input );
}
fn main() {
// i is owned and contains no references, thus it's 'static:
let i = 5;
print_it(i);
// oops, &i only has the lifetime defined by the scope of
// main(), so it's not 'static:
print_it(&i);
}
编译器将会报错:
error[E0597]: `i` does not live long enough
--> src/lib.rs:15:15
|
15 | print_it(&i);
| ---------^^--
| | |
| | borrowed value does not live long enough
| argument requires that `i` is borrowed for `'static`
16 | }
| - `i` dropped here while still borrowed