Merge pull request #321 from Tanish-Eagle/edit

Editing the lifetimesEdit
This commit is contained in:
Sunface 2022-11-07 08:27:57 +08:00 committed by GitHub
commit 718f040a77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 27 deletions

View File

@ -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> {

View File

@ -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.

View File

@ -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;