]>
Commit | Line | Data |
---|---|---|
bd371182 AL |
1 | % `const` and `static` |
2 | ||
3 | Rust has a way of defining constants with the `const` keyword: | |
4 | ||
5 | ```rust | |
6 | const N: i32 = 5; | |
7 | ``` | |
8 | ||
9 | Unlike [`let`][let] bindings, you must annotate the type of a `const`. | |
10 | ||
11 | [let]: variable-bindings.html | |
12 | ||
13 | Constants live for the entire lifetime of a program. More specifically, | |
14 | constants in Rust have no fixed address in memory. This is because they’re | |
15 | effectively inlined to each place that they’re used. References to the same | |
16 | constant are not necessarily guaranteed to refer to the same memory address for | |
17 | this reason. | |
18 | ||
19 | # `static` | |
20 | ||
21 | Rust provides a ‘global variable’ sort of facility in static items. They’re | |
22 | similar to constants, but static items aren’t inlined upon use. This means that | |
23 | there is only one instance for each value, and it’s at a fixed location in | |
24 | memory. | |
25 | ||
26 | Here’s an example: | |
27 | ||
28 | ```rust | |
29 | static N: i32 = 5; | |
30 | ``` | |
31 | ||
32 | Unlike [`let`][let] bindings, you must annotate the type of a `static`. | |
33 | ||
bd371182 | 34 | Statics live for the entire lifetime of a program, and therefore any |
62682a34 | 35 | reference stored in a constant has a [`'static` lifetime][lifetimes]: |
bd371182 AL |
36 | |
37 | ```rust | |
38 | static NAME: &'static str = "Steve"; | |
39 | ``` | |
40 | ||
41 | [lifetimes]: lifetimes.html | |
42 | ||
43 | ## Mutability | |
44 | ||
45 | You can introduce mutability with the `mut` keyword: | |
46 | ||
47 | ```rust | |
48 | static mut N: i32 = 5; | |
49 | ``` | |
50 | ||
51 | Because this is mutable, one thread could be updating `N` while another is | |
52 | reading it, causing memory unsafety. As such both accessing and mutating a | |
53 | `static mut` is [`unsafe`][unsafe], and so must be done in an `unsafe` block: | |
54 | ||
55 | ```rust | |
56 | # static mut N: i32 = 5; | |
57 | ||
58 | unsafe { | |
59 | N += 1; | |
60 | ||
61 | println!("N: {}", N); | |
62 | } | |
63 | ``` | |
64 | ||
65 | [unsafe]: unsafe.html | |
66 | ||
62682a34 SL |
67 | Furthermore, any type stored in a `static` must be `Sync`, and may not have |
68 | a [`Drop`][drop] implementation. | |
69 | ||
70 | [drop]: drop.html | |
bd371182 AL |
71 | |
72 | # Initializing | |
73 | ||
74 | Both `const` and `static` have requirements for giving them a value. They may | |
75 | only be given a value that’s a constant expression. In other words, you cannot | |
76 | use the result of a function call or anything similarly complex or at runtime. | |
77 | ||
78 | # Which construct should I use? | |
79 | ||
80 | Almost always, if you can choose between the two, choose `const`. It’s pretty | |
81 | rare that you actually want a memory location associated with your constant, | |
82 | and using a const allows for optimizations like constant propagation not only | |
83 | in your crate but downstream crates. |