Merge pull request #321 from Tanish-Eagle/edit
Editing the lifetimesEdit
This commit is contained in:
commit
718f040a77
|
@ -1,4 +1,4 @@
|
|||
# advanced lifetime
|
||||
# Advance lifetime
|
||||
|
||||
## Trait Bounds
|
||||
Just like generic types can be bounded, lifetimes can also be bounded as below:
|
||||
|
@ -39,10 +39,10 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
1γπ
|
||||
1,π
|
||||
```rust,editable
|
||||
/* Annotate struct with lifetime:
|
||||
1. `r` and `s` must has different lifetimes
|
||||
1. `r` and `s` must have different lifetimes
|
||||
2. lifetime of `s` is bigger than that of 'r'
|
||||
*/
|
||||
struct DoubleRef<T> {
|
||||
|
@ -55,7 +55,7 @@ fn main() {
|
|||
```
|
||||
|
||||
|
||||
2γππ
|
||||
2,ππ
|
||||
```rust,editable
|
||||
/* Adding trait bounds to make it work */
|
||||
struct ImportantExcerpt<'a> {
|
||||
|
@ -74,7 +74,7 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
3γππ
|
||||
3,ππ
|
||||
```rust,editable
|
||||
/* Adding trait bounds to make it work */
|
||||
fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) {
|
||||
|
@ -98,9 +98,9 @@ impl<'a> PartialEq<i32> for &'a T {
|
|||
|
||||
and could then be used to compare a `&'a T` with any lifetime to an `i32`.
|
||||
|
||||
Only a higher-ranked bound can be used here, because the lifetime of the reference is shorter than any possible lifetime parameter on the functionγ
|
||||
Only a higher-ranked bound can be used here, because the lifetime of the reference is shorter than any possible lifetime parameter on the function.
|
||||
|
||||
4γπππ
|
||||
4,πππ
|
||||
```rust,editable
|
||||
/* Adding HRTB to make it work!*/
|
||||
fn call_on_ref_zero<'a, F>(f: F) where F: Fn(&'a i32) {
|
||||
|
@ -109,7 +109,7 @@ fn call_on_ref_zero<'a, F>(f: F) where F: Fn(&'a i32) {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
println!("Success!")
|
||||
println!("Success!");
|
||||
}
|
||||
```
|
||||
## NLL (Non-Lexical Lifetime)
|
||||
|
@ -187,7 +187,7 @@ fn main() {
|
|||
```
|
||||
|
||||
|
||||
5γππ
|
||||
5,ππ
|
||||
```rust,editable
|
||||
/* Make it work by reordering some code */
|
||||
fn main() {
|
||||
|
@ -214,7 +214,7 @@ impl<'a> Reader for BufReader<'a> {
|
|||
// 'a is not used in the following methods
|
||||
}
|
||||
|
||||
// can be writing as :
|
||||
// can be written as :
|
||||
impl Reader for BufReader<'_> {
|
||||
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ struct Ref<'a, T> {
|
|||
|
||||
## A difficult exercise
|
||||
|
||||
6γππππ
|
||||
6,ππππ
|
||||
```rust,editable
|
||||
/* Make it work */
|
||||
struct Interface<'a> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
## Lifetime
|
||||
The compile uses lifetime to ensure all borrows are valid. Typically, a variable's lifetime begins when it is created and ends when it is destroyed.
|
||||
The compiler uses lifetime to ensure all borrows are valid. Typically, a variable's lifetime begins when it is created and ends when it is destroyed.
|
||||
|
||||
## The scope of lifetime
|
||||
1γ π
|
||||
|
@ -42,7 +42,7 @@ fn main() {
|
|||
|
||||
|
||||
```rust,editable
|
||||
/* annotate `r` and `x` as above, and explain why this code fails to compile, in the lifetime aspect. */
|
||||
/* Annotate `r` and `x` as above, and explain why this code fails to compile, in the lifetime aspect. */
|
||||
|
||||
fn main() {
|
||||
{
|
||||
|
@ -58,16 +58,16 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
## lifetime annotating
|
||||
## Lifetime annotating
|
||||
The **borrow checker uses explicit lifetime annotations** to determine how long a reference should be valid.
|
||||
|
||||
But for us users, in most cases, there is no need to annotate the lifetime, because there are several elision rules, before learning these rules, we need to know how to annotate lifetime manually.
|
||||
|
||||
#### function
|
||||
Ignoring elision rules, lifetimes in function signatures have a few contraintsοΌ
|
||||
#### Function
|
||||
Ignoring elision rules, lifetimes in function signatures have a few constraints:
|
||||
|
||||
- any reference must have an annotated lifetime
|
||||
- any reference being returned must have the same lifetime as one of the inputs or be static
|
||||
- Any reference must have an annotated lifetime
|
||||
- Any reference being returned must have the same lifetime as one of the inputs or be static
|
||||
|
||||
**Example**
|
||||
```rust,editable
|
||||
|
@ -236,7 +236,7 @@ fn main()
|
|||
let example: Example;
|
||||
|
||||
{
|
||||
/* lifetime 'b tied to new stackframe/scope */
|
||||
/* Lifetime 'b tied to new stackframe/scope */
|
||||
let var_b = NoCopyType {};
|
||||
|
||||
/* fixme */
|
||||
|
@ -314,7 +314,7 @@ fn main() {}
|
|||
```
|
||||
|
||||
## Elision
|
||||
Some lifetime patterns are so comman that the borrow checker will allow you to omit them to save typing and to improve readablity.
|
||||
Some lifetime patterns are so comman that the borrow checker will allow you to omit them to save typing and to improve readability.
|
||||
|
||||
This is known as **Elision**. Elision exist in Rust only because these patterns are common.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# &'static and T: 'static
|
||||
`'static` is a reserved lifetime name, you might have encountered it serveral times:
|
||||
`'static` is a reserved lifetime name, you might have encountered it several times:
|
||||
```rust
|
||||
// A reference with 'static lifetime:
|
||||
let s: &'static str = "hello world";
|
||||
|
@ -15,7 +15,7 @@ As a reference lifetime, `&'static` indicates the data pointed to by the referen
|
|||
|
||||
|
||||
|
||||
1γππ There are several ways to make a variable with `'static` lifetime, two of them are stored in the read-only memory of the binaryγ
|
||||
1γππ There are several ways to make a variable with `'static` lifetime, two of them are stored in the read-only memory of the binary.
|
||||
|
||||
```rust,editable
|
||||
|
||||
|
@ -32,7 +32,7 @@ fn need_static(r : &'static str) {
|
|||
}
|
||||
```
|
||||
|
||||
2γ ππππ Another way to make `'static` lifetime is using `Box::leak`
|
||||
2, ππππ Another way to make `'static` lifetime is using `Box::leak`
|
||||
```rust,editable
|
||||
#[derive(Debug)]
|
||||
struct Config {
|
||||
|
@ -59,7 +59,7 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
3γ π `&'static` only indicates that the data can live forever, not the reference. The latter one will be constrained by its scope.
|
||||
3, π `&'static` only indicates that the data can live forever, not the reference. The latter one will be constrained by its scope.
|
||||
```rust,editable
|
||||
fn main() {
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
4γ `&'static` can be coerced to a shorter lifetime.
|
||||
4, `&'static` can be coerced to a shorter lifetime.
|
||||
|
||||
**Example**
|
||||
```rust,editable
|
||||
|
@ -108,9 +108,11 @@ fn main() {
|
|||
## T: 'static
|
||||
As a trait bound, it means the type does not contain any non-static references. Eg. the receiver can hold on to the type for as long as they want and it will never become invalid until they drop it.
|
||||
|
||||
|
||||
It's important to understand this means that any owned data always passes a `'static `lifetime bound, but a reference to that owned data generally does not.
|
||||
|
||||
5γππ
|
||||
|
||||
5,ππ
|
||||
```rust,editable
|
||||
/* Make it work */
|
||||
use std::fmt::Debug;
|
||||
|
@ -145,7 +147,7 @@ fn main() {
|
|||
```
|
||||
|
||||
|
||||
6γπππ
|
||||
6,πππ
|
||||
```rust,editable
|
||||
use std::fmt::Display;
|
||||
|
||||
|
|
Loadingβ¦
Reference in New Issue