TRPL: const and static
This commit is contained in:
parent
3860240b0e
commit
a04f6c5293
|
@ -43,8 +43,7 @@
|
|||
* [Closures](closures.md)
|
||||
* [Universal Function Call Syntax](ufcs.md)
|
||||
* [Crates and Modules](crates-and-modules.md)
|
||||
* [`static`](static.md)
|
||||
* [`const`](const.md)
|
||||
* [`const` and `static`](const-and-static.md)
|
||||
* [Tuple Structs](tuple-structs.md)
|
||||
* [Attributes](attributes.md)
|
||||
* [Conditional Compilation](conditional-compilation.md)
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
% `const` and `static`
|
||||
|
||||
Rust has a way of defining constants with the `const` keyword:
|
||||
|
||||
```rust
|
||||
const N: i32 = 5;
|
||||
```
|
||||
|
||||
Unlike [`let`][let] bindings, you must annotate the type of a `const`.
|
||||
|
||||
[let]: variable-bindings.html
|
||||
|
||||
Constants live for the entire lifetime of a program. More specifically,
|
||||
constants in Rust have no fixed address in memory. This is because they’re
|
||||
effectively inlined to each place that they’re used. References to the same
|
||||
constant are not necessarily guaranteed to refer to the same memory address for
|
||||
this reason.
|
||||
|
||||
# `static`
|
||||
|
||||
Rust provides a ‘global variable’ sort of facility in static items. They’re
|
||||
similar to [constants][const], but static items aren’t inlined upon use. This
|
||||
means that there is only one instance for each value, and it’s at a fixed
|
||||
location in memory.
|
||||
|
||||
Here’s an example:
|
||||
|
||||
```rust
|
||||
static N: i32 = 5;
|
||||
```
|
||||
|
||||
[const]: const.html
|
||||
|
||||
Unlike [`let`][let] bindings, you must annotate the type of a `static`.
|
||||
|
||||
[let]: variable-bindings.html
|
||||
|
||||
Statics live for the entire lifetime of a program, and therefore any
|
||||
reference stored in a constant has a [`’static` lifetime][lifetimes]:
|
||||
|
||||
```rust
|
||||
static NAME: &'static str = "Steve";
|
||||
```
|
||||
|
||||
[lifetimes]: lifetimes.html
|
||||
|
||||
## Mutability
|
||||
|
||||
You can introduce mutability with the `mut` keyword:
|
||||
|
||||
```rust
|
||||
static mut N: i32 = 5;
|
||||
```
|
||||
|
||||
Because this is mutable, one thread could be updating `N` while another is
|
||||
reading it, causing memory unsafety. As such both accessing and mutating a
|
||||
`static mut` is [`unsafe`][unsafe], and so must be done in an `unsafe` block:
|
||||
|
||||
```rust
|
||||
# static mut N: i32 = 5;
|
||||
|
||||
unsafe {
|
||||
N += 1;
|
||||
|
||||
println!("N: {}", N);
|
||||
}
|
||||
```
|
||||
|
||||
Furthermore, any type stored in a `static` must be `Sync`.
|
||||
|
||||
# Initializing
|
||||
|
||||
Both `const` and `static` have requirements for giving them a value. They may
|
||||
only be given a value that’s a constant expression. In other words, you cannot
|
||||
use the result of a function call or anything similarly complex or at runtime.
|
||||
|
||||
# Which construct should I use?
|
||||
|
||||
Almost always, if you can choose between the two, choose `const`. It’s pretty
|
||||
rare that you actually want a memory location associated with your constant,
|
||||
and using a const allows for optimizations like constant propagation not only
|
||||
in your crate but downstream crates.
|
||||
|
||||
A const can be thought of as a `#define` in C: it has metadata overhead but it
|
||||
has no runtime overhead. “Should I use a #define or a static in C,” is largely
|
||||
the same question as whether you should use a const or a static in Rust.
|
|
@ -1,3 +0,0 @@
|
|||
% `const`
|
||||
|
||||
Coming soon!
|
|
@ -1,3 +0,0 @@
|
|||
% `static`
|
||||
|
||||
Coming soon!
|
Loading…
Reference in New Issue