diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index a179f8fa55e5e..238ef6a9394a6 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -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) diff --git a/src/doc/trpl/const-and-static.md b/src/doc/trpl/const-and-static.md new file mode 100644 index 0000000000000..a9d33ccf1f30d --- /dev/null +++ b/src/doc/trpl/const-and-static.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. diff --git a/src/doc/trpl/const.md b/src/doc/trpl/const.md deleted file mode 100644 index 9234c4fc2f9e1..0000000000000 --- a/src/doc/trpl/const.md +++ /dev/null @@ -1,3 +0,0 @@ -% `const` - -Coming soon! diff --git a/src/doc/trpl/static.md b/src/doc/trpl/static.md deleted file mode 100644 index b29c4952c94e3..0000000000000 --- a/src/doc/trpl/static.md +++ /dev/null @@ -1,3 +0,0 @@ -% `static` - -Coming soon!