-
Notifications
You must be signed in to change notification settings - Fork 13.4k
TRPL: const and static #24671
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TRPL: const and static #24671
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't that be "stored in a static"? |
||
|
||
```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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about: Statics and constants can only be initialized using constant expressions, which can only contain a small subset of the full language. If there is a resource that goes into more detail we could link to it here, since that really doesn't give you a lot of information. |
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems wrong: "you cannot use the result […] 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know we've been getting flack recently for not "being systems enough," but I think this analogy could be explained a little more. If someone reading this is not familiar with C this would only be confusing. |
||
the same question as whether you should use a const or a static in Rust. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hehe, this looks familiar :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❤️ |
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would read easier as just:
Constants in Rust have no fixed address in memory because they're effectively inlined to each place they are used. For this reason, references to the same constant are not guaranteed to refer to the same memory address.
Particularly just eliminating the bit about how long constants live, because it's confusing compared to the description of statics.