]> git.proxmox.com Git - rustc.git/blob - src/doc/rust-by-example/src/scope/lifetime/static_lifetime.md
New upstream version 1.74.1+dfsg1
[rustc.git] / src / doc / rust-by-example / src / scope / lifetime / static_lifetime.md
1 # Static
2
3 Rust has a few reserved lifetime names. One of those is `'static`. You
4 might encounter it in two situations:
5
6 ```rust, editable
7 // A reference with 'static lifetime:
8 let s: &'static str = "hello world";
9
10 // 'static as part of a trait bound:
11 fn generic<T>(x: T) where T: 'static {}
12 ```
13
14 Both are related but subtly different and this is a common source for
15 confusion when learning Rust. Here are some examples for each situation:
16
17 ## Reference lifetime
18
19 As a reference lifetime `'static` indicates that the data pointed to by
20 the reference lives for the remaining lifetime of the running program.
21 It can still be coerced to a shorter lifetime.
22
23 There are two common ways to make a variable with `'static` lifetime, and both
24 are stored in the read-only memory of the binary:
25
26 * Make a constant with the `static` declaration.
27 * Make a `string` literal which has type: `&'static str`.
28
29 See the following example for a display of each method:
30
31 ```rust,editable
32 // Make a constant with `'static` lifetime.
33 static NUM: i32 = 18;
34
35 // Returns a reference to `NUM` where its `'static`
36 // lifetime is coerced to that of the input argument.
37 fn coerce_static<'a>(_: &'a i32) -> &'a i32 {
38 &NUM
39 }
40
41 fn main() {
42 {
43 // Make a `string` literal and print it:
44 let static_string = "I'm in read-only memory";
45 println!("static_string: {}", static_string);
46
47 // When `static_string` goes out of scope, the reference
48 // can no longer be used, but the data remains in the binary.
49 }
50
51 {
52 // Make an integer to use for `coerce_static`:
53 let lifetime_num = 9;
54
55 // Coerce `NUM` to lifetime of `lifetime_num`:
56 let coerced_static = coerce_static(&lifetime_num);
57
58 println!("coerced_static: {}", coerced_static);
59 }
60
61 println!("NUM: {} stays accessible!", NUM);
62 }
63 ```
64
65 Since `'static` references only need to be valid for the _remainder_ of
66 a program's life, they can be created while the program is executed. Just to
67 demonstrate, the below example uses
68 [`Box::leak`](https://doc.rust-lang.org/std/boxed/struct.Box.html#method.leak)
69 to dynamically create `'static` references. In that case it definitely doesn't
70 live for the entire duration, but only for the leaking point onward.
71
72 ```rust,editable,compile_fail
73 extern crate rand;
74 use rand::Fill;
75
76 fn random_vec() -> &'static [usize; 100] {
77 let mut rng = rand::thread_rng();
78 let mut boxed = Box::new([0; 100]);
79 boxed.try_fill(&mut rng).unwrap();
80 Box::leak(boxed)
81 }
82
83 fn main() {
84 let first: &'static [usize; 100] = random_vec();
85 let second: &'static [usize; 100] = random_vec();
86 assert_ne!(first, second)
87 }
88 ```
89
90 ## Trait bound
91
92 As a trait bound, it means the type does not contain any non-static
93 references. Eg. the receiver can hold on to the type for as long as
94 they want and it will never become invalid until they drop it.
95
96 It's important to understand this means that any owned data always passes
97 a `'static` lifetime bound, but a reference to that owned data generally
98 does not:
99
100 ```rust,editable,compile_fail
101 use std::fmt::Debug;
102
103 fn print_it( input: impl Debug + 'static ) {
104 println!( "'static value passed in is: {:?}", input );
105 }
106
107 fn main() {
108 // i is owned and contains no references, thus it's 'static:
109 let i = 5;
110 print_it(i);
111
112 // oops, &i only has the lifetime defined by the scope of
113 // main(), so it's not 'static:
114 print_it(&i);
115 }
116 ```
117 The compiler will tell you:
118 ```ignore
119 error[E0597]: `i` does not live long enough
120 --> src/lib.rs:15:15
121 |
122 15 | print_it(&i);
123 | ---------^^--
124 | | |
125 | | borrowed value does not live long enough
126 | argument requires that `i` is borrowed for `'static`
127 16 | }
128 | - `i` dropped here while still borrowed
129 ```
130
131 ### See also:
132
133 [`'static` constants][static_const]
134
135 [static_const]: ../../custom_types/constants.md