-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Fight the confusion over 'static #1316
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 |
---|---|---|
@@ -1,15 +1,61 @@ | ||
# Static | ||
|
||
A `'static` lifetime is the longest possible lifetime, and lasts for | ||
the lifetime of the running program. A `'static` lifetime may also be | ||
coerced to a shorter lifetime. There are two ways to make a variable | ||
with `'static` lifetime, and both are stored in the read-only memory | ||
of the binary: | ||
`'static` is one of the reserved lifetime specifiers. It has a special meaning | ||
in Rust. A __reference__ that has a `'static` lifetime is guaranteed to be | ||
valid for the entire lifetime of the running program. | ||
|
||
There are two ways to create data that lives for the entire lifetime of | ||
a program and both are stored in the read-only memory of the binary: | ||
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 is also not the only two ways: owned values are 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. The two points where there in the original text. The PR tries to make the distinction between I don't know if you are just reading the diff, it might be worth to zoom out and read both versions in their entirety. |
||
|
||
* Make a constant with the `static` declaration. | ||
* Make a `string` literal which has type: `&'static str`. | ||
|
||
See the following example for a display of each method: | ||
__Warning__: It's easy to get confused about `'static` because all variable | ||
bindings that own their data, eg. do not contain references, fulfill a | ||
bound on `'static`: | ||
|
||
```rust,editable,compile_fail | ||
use std::fmt::Debug; | ||
|
||
fn print_it( input: impl Debug + 'static ) | ||
{ | ||
println!( "'static value passed in is: {:?}", input ); | ||
} | ||
|
||
fn use_it() | ||
{ | ||
let i = 5; // i is owned and contains no references, thus it's 'static | ||
print_it( i ); // valid call | ||
|
||
// oops, &i only has the lifetime defined by the scope of | ||
// use_it(), so it's not 'static | ||
print_it( &i ); | ||
} | ||
``` | ||
|
||
|
||
The compiler will tell you: | ||
```ignore | ||
error[E0597]: `i` does not live long enough | ||
--> src/lib.rs:15:15 | ||
| | ||
15 | print_it( &i ); | ||
| ----------^^-- | ||
| | | | ||
| | borrowed value does not live long enough | ||
| argument requires that `i` is borrowed for `'static` | ||
16 | } | ||
| - `i` dropped here while still borrowed | ||
``` | ||
|
||
A bound on `'static` means that the callee does not have to worry | ||
about their variable binding becoming invalid after some time. | ||
They can use it as long as they want. In contrast to a `'static` | ||
__reference__, this is unrelated to the runtime of the entire program. | ||
|
||
A `'static` lifetime may also be coerced to a shorter lifetime. | ||
|
||
See the following example for uses of `'static`: | ||
|
||
```rust,editable | ||
// Make a constant with `'static` lifetime. | ||
|
@@ -49,4 +95,4 @@ fn main() { | |
|
||
[`'static` constants][static_const] | ||
|
||
[static_const]: ../../custom_types/constants.md | ||
[static_const]: ../../custom_types/constants.md |
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.
This is not quite correct. It may live for the entire lifetime, but does not have to.
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.
Do you mean that if I had an API that takes in a
&'static Something
it would possibly stop being valid at some point before the end of the program? That seems problematic, no? How do you know when?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.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c7241593e258fdc2ba77c6b603c15bb5
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.
Ok, but now we are confusing with the lifetime of the variable binding of the reference. I generally assumed that when we speak about reference lifetimes, we mean the lifetime of the pointed to data and the one we name as in
&'a SomeValue
->'a
in this case. The text says "the reference is guaranteed to be valid", as opposed to "The reference lives for ...". Of course you are allowed to drop it sooner if you don't need it anymore. Given that beginners will most often read the book, this is probably a bad assumption on my part.But if you feel that that is still not clear enough, I will propose a complete rewrite. I am generally in favor of being very precise and thorough, but often my documentation PR's get downplayed, so I didn't necessarily proposed the way I like it best but more as what I estimate the general opinion might be. It will probably be a fair bit longer if trying to be complete. I suppose also that in RBE we prefer showing code rather than long descriptions?