fix: change 、to .

This commit is contained in:
katopz 2022-11-07 11:06:19 +07:00
parent 14a2600176
commit a46840763e
No known key found for this signature in database
GPG Key ID: C17323088013E8B8
13 changed files with 105 additions and 105 deletions

View File

@ -41,7 +41,7 @@ Closures can capture variables by borrowing or moving. But they prefer to captur
- by mutable reference: `&mut T` - by mutable reference: `&mut T`
- by value: `T` - by value: `T`
1🌟 1. 🌟
```rust,editable ```rust,editable
/* Make it work with least changing */ /* Make it work with least changing */
fn main() { fn main() {
@ -60,7 +60,7 @@ fn main() {
} }
``` ```
2🌟🌟 2. 🌟🌟
```rust,editable ```rust,editable
/* Make it work /* Make it work
- Dont use `_reborrow` and `_count_reborrowed` - Dont use `_reborrow` and `_count_reborrowed`
@ -89,7 +89,7 @@ fn main() {
} }
``` ```
3🌟🌟 3. 🌟🌟
```rust,editable ```rust,editable
/* Make it work in two ways, none of them is to remove `take(movable)` away from the code /* Make it work in two ways, none of them is to remove `take(movable)` away from the code
*/ */
@ -132,7 +132,7 @@ let add_one_v3 = |x| { x + 1 };
let add_one_v4 = |x| x + 1 ; let add_one_v4 = |x| x + 1 ;
``` ```
4🌟 4. 🌟
```rust,editable ```rust,editable
fn main() { fn main() {
let example_closure = |x| x; let example_closure = |x| x;
@ -151,7 +151,7 @@ When taking a closure as an input parameter, the closure's complete type must be
- FnMut: the closure uses the captured value by mutable reference (&mut T) - FnMut: the closure uses the captured value by mutable reference (&mut T)
- FnOnce: the closure uses the captured value by value (T) - FnOnce: the closure uses the captured value by value (T)
5🌟🌟 5. 🌟🌟
```rust,editable ```rust,editable
/* Make it work by change the trait bound, in two ways*/ /* Make it work by change the trait bound, in two ways*/
fn fn_once<F>(func: F) fn fn_once<F>(func: F)
@ -168,7 +168,7 @@ fn main() {
} }
``` ```
6 🌟🌟 6. 🌟🌟
```rust,editable ```rust,editable
fn main() { fn main() {
let mut s = String::new(); let mut s = String::new();
@ -198,7 +198,7 @@ Which trait to use is determined by what the closure does with captured value.
This is because if a move is possible, then any type of borrow should also be possible. Note that the reverse is not true. If the parameter is annotated as `Fn`, then capturing variables by `&mut T` or `T` are not allowed. This is because if a move is possible, then any type of borrow should also be possible. Note that the reverse is not true. If the parameter is annotated as `Fn`, then capturing variables by `&mut T` or `T` are not allowed.
7🌟🌟 7. 🌟🌟
```rust,editable ```rust,editable
/* Fill in the blank */ /* Fill in the blank */
@ -285,7 +285,7 @@ fn exec<F: Fn()>(f: F) {
} }
``` ```
8🌟🌟 8. 🌟🌟
```rust,editable ```rust,editable
/* Fill in the blank */ /* Fill in the blank */
fn main() { fn main() {
@ -305,7 +305,7 @@ fn exec<'a, F: __>(mut f: F) {
## Input functions ## Input functions
Since closure maybe used as arguments, you might wonder can we use functions as arguments too? And indeed they can. Since closure maybe used as arguments, you might wonder can we use functions as arguments too? And indeed they can.
9🌟🌟 9. 🌟🌟
```rust,editable ```rust,editable
/* Implement `call_me` to make it work */ /* Implement `call_me` to make it work */
@ -328,7 +328,7 @@ fn main() {
## Closure as return types ## Closure as return types
Returning a closure is much harder than you may thought of. Returning a closure is much harder than you may thought of.
10🌟🌟 10. 🌟🌟
```rust,editable ```rust,editable
/* Fill in the blank using two approches, /* Fill in the blank using two approches,
and fix the errror */ and fix the errror */
@ -347,7 +347,7 @@ fn main() {
} }
``` ```
11🌟🌟 11. 🌟🌟
```rust,editable ```rust,editable
/* Fill in the blank and fix the error*/ /* Fill in the blank and fix the error*/
fn factory(x:i32) -> __ { fn factory(x:i32) -> __ {

View File

@ -23,7 +23,7 @@ fn main() {
} }
``` ```
1🌟 1. 🌟
```rust,editable ```rust,editable
/* Refactoring the following code using iterators */ /* Refactoring the following code using iterators */
fn main() { fn main() {
@ -34,7 +34,7 @@ fn main() {
} }
``` ```
2 🌟 One of the easiest ways to create an iterator is to use the range notion: `a..b`. 2. 🌟 One of the easiest ways to create an iterator is to use the range notion: `a..b`.
```rust,editable ```rust,editable
/* Fill in the blank */ /* Fill in the blank */
fn main() { fn main() {
@ -61,7 +61,7 @@ pub trait Iterator {
And we can call the `next` method on iterators directly. And we can call the `next` method on iterators directly.
3🌟🌟 3. 🌟🌟
```rust,editable ```rust,editable
/* Fill the blanks and fix the errors. /* Fill the blanks and fix the errors.
Using two ways if possible */ Using two ways if possible */
@ -83,7 +83,7 @@ In the previous section, we have mentioned that `for` will apply the `into_iter`
- `iter`, this borrows each element of the collection through each iteration, thus leaving the collection untouched and available for reuse after the loop - `iter`, this borrows each element of the collection through each iteration, thus leaving the collection untouched and available for reuse after the loop
- `iter_mut`, this mutably borrows each element of the collection, allowing for the collection to be modified in place. - `iter_mut`, this mutably borrows each element of the collection, allowing for the collection to be modified in place.
4🌟 4. 🌟
```rust,editable ```rust,editable
/* Make it work */ /* Make it work */
fn main() { fn main() {
@ -96,7 +96,7 @@ fn main() {
} }
``` ```
5🌟 5. 🌟
```rust,editable ```rust,editable
/* Fill in the blank */ /* Fill in the blank */
fn main() { fn main() {
@ -113,7 +113,7 @@ fn main() {
} }
``` ```
6🌟🌟 6. 🌟🌟
```rust,editable ```rust,editable
/* Fill in the blank */ /* Fill in the blank */
fn main() { fn main() {
@ -169,7 +169,7 @@ fn main() {
} }
``` ```
7🌟🌟🌟 7. 🌟🌟🌟
```rust,editable ```rust,editable
struct Fibonacci { struct Fibonacci {
curr: u32, curr: u32,
@ -208,7 +208,7 @@ The `Iterator` trait has a number of methods with default implementations provid
### Consuming adaptors ### Consuming adaptors
Some of these methods call the method `next`to use up the iterator, so they are called *consuming adaptors*. Some of these methods call the method `next`to use up the iterator, so they are called *consuming adaptors*.
8🌟🌟 8. 🌟🌟
```rust,edtiable ```rust,edtiable
/* Fill in the blank and fix the errors */ /* Fill in the blank and fix the errors */
fn main() { fn main() {
@ -229,7 +229,7 @@ fn main() {
#### collect #### collect
Other than converting a collection into an iterator, we can also `collect` the result values into a collection, `collect` will cosume the iterator. Other than converting a collection into an iterator, we can also `collect` the result values into a collection, `collect` will cosume the iterator.
9🌟🌟 9. 🌟🌟
```rust,editable ```rust,editable
/* Make it work */ /* Make it work */
use std::collections::HashMap; use std::collections::HashMap;
@ -253,7 +253,7 @@ Methods allowing you to change one iterator into another iterator are known as *
But because **all iterators are lazy**, you have to call one of the consuming adapers to get results from calls to iterator adapters. But because **all iterators are lazy**, you have to call one of the consuming adapers to get results from calls to iterator adapters.
10🌟🌟 10. 🌟🌟
```rust,editable ```rust,editable
/* Fill in the blanks */ /* Fill in the blanks */
fn main() { fn main() {
@ -265,7 +265,7 @@ fn main() {
} }
``` ```
11🌟🌟 11. 🌟🌟
```rust ```rust
/* Fill in the blanks */ /* Fill in the blanks */
use std::collections::HashMap; use std::collections::HashMap;
@ -281,7 +281,7 @@ fn main() {
#### Using closures in iterator adaptors #### Using closures in iterator adaptors
12🌟🌟 12. 🌟🌟
```rust ```rust
/* Fill in the blanks */ /* Fill in the blanks */
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]

View File

@ -2,7 +2,7 @@
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 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 ## The scope of lifetime
1 🌟 1. 🌟
```rust,editable ```rust,editable
/* Annotate the lifetime of `i` and `borrow2` */ /* Annotate the lifetime of `i` and `borrow2` */
@ -109,7 +109,7 @@ fn main() {
} }
``` ```
3 🌟 3. 🌟
```rust,editable ```rust,editable
/* Make it work by adding proper lifetime annotation */ /* Make it work by adding proper lifetime annotation */
fn longest(x: &str, y: &str) -> &str { fn longest(x: &str, y: &str) -> &str {
@ -122,7 +122,7 @@ fn longest(x: &str, y: &str) -> &str {
fn main() {} fn main() {}
``` ```
4🌟🌟🌟 4. 🌟🌟🌟
```rust,editable ```rust,editable
// `'a` must live longer than the function. // `'a` must live longer than the function.
// Here, `&String::from("foo")` would create a `String`, followed by a // Here, `&String::from("foo")` would create a `String`, followed by a
@ -138,7 +138,7 @@ fn main() {
} }
``` ```
5🌟🌟 5. 🌟🌟
```rust,editable ```rust,editable
// `print_refs` takes two references to `i32` which have different // `print_refs` takes two references to `i32` which have different
// lifetimes `'a` and `'b`. These two lifetimes must both be at // lifetimes `'a` and `'b`. These two lifetimes must both be at
@ -176,7 +176,7 @@ fn main() {
``` ```
#### Structs #### Structs
6 🌟 6. 🌟
```rust,editable ```rust,editable
/* Make it work by adding proper lifetime annotation */ /* Make it work by adding proper lifetime annotation */
@ -216,7 +216,7 @@ fn main() {
``` ```
7 🌟🌟 7. 🌟🌟
```rust,editable ```rust,editable
/* Make it work */ /* Make it work */
@ -248,7 +248,7 @@ fn main()
``` ```
8 🌟🌟 8. 🌟🌟
```rust,editable ```rust,editable
#[derive(Debug)] #[derive(Debug)]
@ -297,7 +297,7 @@ fn main() {
} }
``` ```
9🌟🌟 9. 🌟🌟
```rust,editable ```rust,editable
/* Make it work by adding proper lifetime annotations */ /* Make it work by adding proper lifetime annotations */
struct ImportantExcerpt { struct ImportantExcerpt {
@ -320,7 +320,7 @@ This is known as **Elision**. Elision exist in Rust only because these patterns
For a more comprehensive understanding of elision, please see [lifetime elision](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-elision) in the official book. For a more comprehensive understanding of elision, please see [lifetime elision](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-elision) in the official book.
10🌟🌟 10. 🌟🌟
```rust,editable ```rust,editable
/* Remove all the lifetimes that can be elided */ /* Remove all the lifetimes that can be elided */

View File

@ -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 ```rust,editable

View File

@ -5,7 +5,7 @@ The orphan rule tells us that we are allowed to implement a trait on a type as l
The **newtype pattern** can help us get around this restriction, which involves creating a new type in a **tuple struct**. The **newtype pattern** can help us get around this restriction, which involves creating a new type in a **tuple struct**.
1🌟 1. 🌟
```rust,editable ```rust,editable
use std::fmt; use std::fmt;
@ -26,7 +26,7 @@ fn main() {
} }
``` ```
2🌟 Hide the methods of the original type 2. 🌟 Hide the methods of the original type
```rust,editable ```rust,editable
/* Make it workd */ /* Make it workd */
struct Meters(u32); struct Meters(u32);
@ -41,7 +41,7 @@ fn main() {
} }
``` ```
3🌟🌟 The `newtype` idiom gives compile time guarantees that the right type of value is suplied to a program. 3. 🌟🌟 The `newtype` idiom gives compile time guarantees that the right type of value is suplied to a program.
```rust,editable ```rust,editable
/* Make it work */ /* Make it work */
struct Years(i64); struct Years(i64);
@ -74,7 +74,7 @@ fn main() {
} }
``` ```
4🌟🌟 4. 🌟🌟
```rust,editable ```rust,editable
use std::ops::Add; use std::ops::Add;
use std::fmt::{self, format}; use std::fmt::{self, format};
@ -133,7 +133,7 @@ let y: Meters = 5;
println!("x + y = {}", x + y); println!("x + y = {}", x + y);
``` ```
5🌟 5. 🌟
```rust,editable ```rust,editable
enum VeryVerboseEnumOfThingsToDoWithNumbers { enum VeryVerboseEnumOfThingsToDoWithNumbers {
Add, Add,
@ -150,7 +150,7 @@ fn main() {
} }
``` ```
6🌟🌟 There are a few preserved alias in Rust, one of which can be used in `impl` blocks. 6. 🌟🌟 There are a few preserved alias in Rust, one of which can be used in `impl` blocks.
```rust,editable ```rust,editable
enum VeryVerboseEnumOfThingsToDoWithNumbers { enum VeryVerboseEnumOfThingsToDoWithNumbers {
Add, Add,
@ -170,7 +170,7 @@ impl VeryVerboseEnumOfThingsToDoWithNumbers {
## DST and unsized type ## DST and unsized type
These concepts are complicated, so we are not going to explain here, but you can find them in [The Book](https://doc.rust-lang.org/book/ch19-04-advanced-types.html?highlight=DST#dynamically-sized-types-and-the-sized-trait). These concepts are complicated, so we are not going to explain here, but you can find them in [The Book](https://doc.rust-lang.org/book/ch19-04-advanced-types.html?highlight=DST#dynamically-sized-types-and-the-sized-trait).
7🌟🌟🌟 Array with dynamic length is a Dynamic Sized Type ( DST ), we can't directly use it 7. 🌟🌟🌟 Array with dynamic length is a Dynamic Sized Type ( DST ), we can't directly use it
```rust,editable ```rust,editable
/* Make it work with const generics */ /* Make it work with const generics */
fn my_function(n: usize) -> [u32; usize] { fn my_function(n: usize) -> [u32; usize] {
@ -183,7 +183,7 @@ fn main() {
} }
``` ```
8🌟🌟 Slice is unsized type, but the reference of slice is not. 8. 🌟🌟 Slice is unsized type, but the reference of slice is not.
```rust,editable ```rust,editable
/* Make it work with slice references */ /* Make it work with slice references */
fn main() { fn main() {
@ -193,7 +193,7 @@ fn main() {
} }
``` ```
9🌟🌟 Trait is also a unsized type 9. 🌟🌟 Trait is also a unsized type
```rust,editable ```rust,editable
/* Make it work in two ways */ /* Make it work in two ways */
use std::fmt::Display; use std::fmt::Display;

View File

@ -1,4 +1,4 @@
1 1.
```rust ```rust
fn main() { fn main() {
@ -13,7 +13,7 @@ fn main() {
} }
``` ```
2 2.
```rust ```rust
fn main() { fn main() {
@ -39,7 +39,7 @@ fn main() {
} }
``` ```
3 3.
```rust ```rust
fn main() { fn main() {
@ -85,7 +85,7 @@ fn take<T>(_v: &T) {
} }
``` ```
4 4.
```rust ```rust
fn main() { fn main() {
@ -98,7 +98,7 @@ fn main() {
} }
``` ```
5 5.
```rust ```rust
fn fn_once<F>(func: F) fn fn_once<F>(func: F)
@ -130,7 +130,7 @@ fn main() {
} }
``` ```
6 6.
```rust ```rust
fn main() { fn main() {
@ -148,7 +148,7 @@ fn exec<'a, F: FnMut(&'a str)>(mut f: F) {
} }
``` ```
7 7.
```rust ```rust
// A function which takes a closure as an argument and calls it. // A function which takes a closure as an argument and calls it.
@ -203,7 +203,7 @@ fn main() {
} }
``` ```
8 8.
```rust ```rust
fn main() { fn main() {
@ -219,7 +219,7 @@ fn exec<'a, F: FnOnce(&'a str) -> String>(mut f: F) {
} }
``` ```
9 9.
```rust ```rust
// Define a function which takes a generic `F` argument // Define a function which takes a generic `F` argument
@ -242,7 +242,7 @@ fn main() {
} }
``` ```
10 10.
```rust ```rust
/* Fill in the blank and fix the errror */ /* Fill in the blank and fix the errror */
@ -277,7 +277,7 @@ fn main() {
} }
``` ```
11 11.
```rust ```rust
// Every closure has its own type. Even if one closure has the same representation as another, their types are different. // Every closure has its own type. Even if one closure has the same representation as another, their types are different.

View File

@ -1,4 +1,4 @@
1 1.
```rust ```rust
fn main() { fn main() {
@ -9,7 +9,7 @@ fn main() {
} }
``` ```
2 2.
```rust ```rust
fn main() { fn main() {
@ -22,7 +22,7 @@ fn main() {
} }
``` ```
3 3.
```rust ```rust
fn main() { fn main() {
@ -50,7 +50,7 @@ fn main() {
} }
``` ```
4 4.
```rust ```rust
fn main() { fn main() {
@ -63,7 +63,7 @@ fn main() {
} }
``` ```
5 5.
```rust ```rust
fn main() { fn main() {
@ -80,7 +80,7 @@ fn main() {
} }
``` ```
6 6.
```rust ```rust
fn main() { fn main() {
@ -95,7 +95,7 @@ fn main() {
} }
``` ```
7 7.
```rust ```rust
struct Fibonacci { struct Fibonacci {
@ -142,7 +142,7 @@ fn main() {
} }
``` ```
8 8.
```rust ```rust
fn main() { fn main() {
@ -159,7 +159,7 @@ fn main() {
} }
``` ```
9 9.
```rust ```rust
use std::collections::HashMap; use std::collections::HashMap;
@ -177,7 +177,7 @@ fn main() {
} }
``` ```
10 10.
```rust ```rust
fn main() { fn main() {
@ -189,7 +189,7 @@ fn main() {
} }
``` ```
11 11.
```rust ```rust
use std::collections::HashMap; use std::collections::HashMap;
@ -202,7 +202,7 @@ fn main() {
} }
``` ```
12 12.
```rust ```rust
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]

View File

@ -1,4 +1,4 @@
1 1.
```rust ```rust
struct DoubleRef<'a,'b:'a, T> { struct DoubleRef<'a,'b:'a, T> {
@ -10,7 +10,7 @@ fn main() {
} }
``` ```
2 2.
```rust ```rust
struct ImportantExcerpt<'a> { struct ImportantExcerpt<'a> {
@ -29,7 +29,7 @@ fn main() {
} }
``` ```
3 3.
```rust ```rust
fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) where 'a: 'b { fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) where 'a: 'b {
@ -41,7 +41,7 @@ fn main() {
} }
``` ```
4 4.
```rust ```rust
fn call_on_ref_zero<F>(f: F) where for<'a> F: Fn(&'a i32) { fn call_on_ref_zero<F>(f: F) where for<'a> F: Fn(&'a i32) {
@ -65,7 +65,7 @@ fn call_on_ref_zero<F>(f: F) where F: for<'a> Fn(&'a i32) {
} }
``` ```
5 5.
```rust ```rust
fn main() { fn main() {
@ -80,7 +80,7 @@ fn main() {
} }
``` ```
6 6.
```rust ```rust
struct Interface<'b, 'a: 'b> { struct Interface<'b, 'a: 'b> {

View File

@ -1,4 +1,4 @@
1 1.
```rust ```rust
fn main() { fn main() {
@ -26,7 +26,7 @@ fn need_static(r : &'static str) {
} }
``` ```
2 2.
```rust ```rust
#[derive(Debug)] #[derive(Debug)]
@ -55,7 +55,7 @@ fn main() {
} }
``` ```
3 3.
```rust ```rust
fn main() { fn main() {
@ -67,7 +67,7 @@ fn main() {
} }
``` ```
5 5.
```rust ```rust
use std::fmt::Debug; use std::fmt::Debug;

View File

@ -1,4 +1,4 @@
1 1.
```rust ```rust
use std::fmt; use std::fmt;
@ -17,7 +17,7 @@ fn main() {
} }
``` ```
2 2.
```rust ```rust
struct Meters(u32); struct Meters(u32);
@ -31,7 +31,7 @@ fn main() {
} }
``` ```
3 3.
```rust ```rust
struct Years(i64); struct Years(i64);
@ -64,7 +64,7 @@ fn main() {
} }
``` ```
4Sometimes `newtype` pattern can provide extra readability. 4. Sometimes `newtype` pattern can provide extra readability.
```rust ```rust
use std::ops::Add; use std::ops::Add;
@ -97,7 +97,7 @@ fn calculate_distance(d1: Meters, d2: Meters) -> Meters {
} }
``` ```
5 5.
```rust ```rust
enum VeryVerboseEnumOfThingsToDoWithNumbers { enum VeryVerboseEnumOfThingsToDoWithNumbers {
@ -115,7 +115,7 @@ fn main() {
} }
``` ```
6 6.
```rust ```rust
enum VeryVerboseEnumOfThingsToDoWithNumbers { enum VeryVerboseEnumOfThingsToDoWithNumbers {
@ -135,7 +135,7 @@ impl VeryVerboseEnumOfThingsToDoWithNumbers {
fn main() {} fn main() {}
``` ```
7 7.
```rust ```rust
fn my_function<const N: usize>() -> [u32; N] { fn my_function<const N: usize>() -> [u32; N] {
@ -148,7 +148,7 @@ fn main() {
} }
``` ```
8 8.
```rust ```rust
fn main() { fn main() {
@ -158,7 +158,7 @@ fn main() {
} }
``` ```
9 9.
```rust ```rust
use std::fmt::Display; use std::fmt::Display;

View File

@ -39,7 +39,7 @@ fn main() {
} }
``` ```
1🌟 1. 🌟
```rust,editable ```rust,editable
/* 使用生命周期注释结构体 /* 使用生命周期注释结构体
1. `r``s` 必须是不同生命周期 1. `r``s` 必须是不同生命周期
@ -55,7 +55,7 @@ fn main() {
``` ```
2🌟🌟 2. 🌟🌟
```rust,editable ```rust,editable
/* 添加类型约束使下面代码正常运行 */ /* 添加类型约束使下面代码正常运行 */
struct ImportantExcerpt<'a> { struct ImportantExcerpt<'a> {
@ -74,7 +74,7 @@ fn main() {
} }
``` ```
3🌟🌟 3. 🌟🌟
```rust,editable ```rust,editable
/* 添加类型约束使下面代码正常运行 */ /* 添加类型约束使下面代码正常运行 */
fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) { fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) {
@ -100,7 +100,7 @@ impl<'a> PartialEq<i32> for &'a T {
这里只能使用更高级别的约束,因为引用的生命周期比函数上任何可能的生命周期参数都短。 这里只能使用更高级别的约束,因为引用的生命周期比函数上任何可能的生命周期参数都短。
4🌟🌟🌟 4. 🌟🌟🌟
```rust ```rust
/* 添加 HRTB 使下面代码正常运行! */ /* 添加 HRTB 使下面代码正常运行! */
fn call_on_ref_zero<'a, F>(f: F) where F: Fn(&'a i32) { fn call_on_ref_zero<'a, F>(f: F) where F: Fn(&'a i32) {
@ -188,7 +188,7 @@ fn main() {
``` ```
5🌟🌟 5. 🌟🌟
```rust,editable ```rust,editable
/* 通过重新排序一些代码使下面代码正常运行 */ /* 通过重新排序一些代码使下面代码正常运行 */
fn main() { fn main() {
@ -236,7 +236,7 @@ struct Ref<'a, T> {
## 艰难的练习 ## 艰难的练习
6🌟🌟🌟🌟 6. 🌟🌟🌟🌟
```rust ```rust
/* 使下面代码正常运行 */ /* 使下面代码正常运行 */
struct Interface<'a> { struct Interface<'a> {

View File

@ -4,7 +4,7 @@
## 生命周期的范围 ## 生命周期的范围
1 🌟 1. 🌟
```rust,editable ```rust,editable
/* 为 `i``borrow2` 标注合适的生命周期范围 */ /* 为 `i``borrow2` 标注合适的生命周期范围 */
@ -106,7 +106,7 @@ fn main() {
} }
``` ```
3 🌟 3. 🌟
```rust,editable ```rust,editable
/* 添加合适的生命周期标注,让下面的代码工作 */ /* 添加合适的生命周期标注,让下面的代码工作 */
fn longest(x: &str, y: &str) -> &str { fn longest(x: &str, y: &str) -> &str {
@ -119,7 +119,7 @@ fn longest(x: &str, y: &str) -> &str {
fn main() {} fn main() {}
``` ```
4🌟🌟🌟 4. 🌟🌟🌟
```rust,editable ```rust,editable
/* 使用三种方法修复下面的错误 */ /* 使用三种方法修复下面的错误 */
fn invalid_output<'a>() -> &'a String { fn invalid_output<'a>() -> &'a String {
@ -130,7 +130,7 @@ fn main() {
} }
``` ```
5🌟🌟 5. 🌟🌟
```rust,editable ```rust,editable
// `print_refs` 有两个引用参数,它们的生命周期 `'a``'b` 至少得跟函数活得一样久 // `print_refs` 有两个引用参数,它们的生命周期 `'a``'b` 至少得跟函数活得一样久
fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) { fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) {
@ -161,7 +161,7 @@ fn main() {
``` ```
#### Structs #### Structs
6 🌟 6. 🌟
```rust,editable ```rust,editable
/* 增加合适的生命周期标准,让代码工作 */ /* 增加合适的生命周期标准,让代码工作 */
@ -199,7 +199,7 @@ fn main() {
``` ```
7 🌟🌟 7. 🌟🌟
```rust,editable ```rust,editable
/* 让代码工作 */ /* 让代码工作 */
@ -229,7 +229,7 @@ fn main()
``` ```
8 🌟🌟 8. 🌟🌟
```rust,editable ```rust,editable
#[derive(Debug)] #[derive(Debug)]
@ -277,7 +277,7 @@ fn main() {
} }
``` ```
9🌟🌟 9. 🌟🌟
```rust,editable ```rust,editable
/* 添加合适的生命周期让下面代码工作 */ /* 添加合适的生命周期让下面代码工作 */
struct ImportantExcerpt { struct ImportantExcerpt {
@ -300,7 +300,7 @@ fn main() {}
这种规则被称为生命周期消除规则( Elision ),该规则之所以存在,仅仅是因为这些场景太通用了,为了方便用户而已。事实上对于借用检查器而言,该有的生命周期一个都不能少,只不过对于用户而言,可以省去一些。 这种规则被称为生命周期消除规则( Elision ),该规则之所以存在,仅仅是因为这些场景太通用了,为了方便用户而已。事实上对于借用检查器而言,该有的生命周期一个都不能少,只不过对于用户而言,可以省去一些。
10🌟🌟 10. 🌟🌟
```rust,editable ```rust,editable
/* 移除所有可以消除的生命周期标注 */ /* 移除所有可以消除的生命周期标注 */

View File

@ -13,7 +13,7 @@ fn generic<T>(x: T) where T: 'static {}
## &'static ## &'static
作为一个引用生命周期,`&'static` 说明该引用指向的数据可以跟程序活得一样久,但是该引用的生命周期依然有可能被强转为一个更短的生命周期。 作为一个引用生命周期,`&'static` 说明该引用指向的数据可以跟程序活得一样久,但是该引用的生命周期依然有可能被强转为一个更短的生命周期。
1🌟🌟 有好几种方法可以将一个变量标记为 `'static` 生命周期, 其中两种都是和保存在二进制文件中相关( 例如字符串字面量就是保存在二进制文件中,它的生命周期是 `'static` )。 1. 🌟🌟 有好几种方法可以将一个变量标记为 `'static` 生命周期, 其中两种都是和保存在二进制文件中相关( 例如字符串字面量就是保存在二进制文件中,它的生命周期是 `'static` )。
```rust,editable ```rust,editable
@ -30,7 +30,7 @@ fn need_static(r : &'static str) {
} }
``` ```
2 🌟🌟🌟🌟 使用 `Box::leak` 也可以产生 `'static` 生命周期 2. 🌟🌟🌟🌟 使用 `Box::leak` 也可以产生 `'static` 生命周期
```rust,editable ```rust,editable
#[derive(Debug)] #[derive(Debug)]
struct Config { struct Config {
@ -57,7 +57,7 @@ fn main() {
} }
``` ```
3 🌟 `&'static` 只能说明引用指向的数据是能一直存活的,但是引用本身依然受限于它的作用域 3. 🌟 `&'static` 只能说明引用指向的数据是能一直存活的,但是引用本身依然受限于它的作用域
```rust,editable ```rust,editable
fn main() { fn main() {
{ {
@ -72,7 +72,7 @@ fn main() {
} }
``` ```
4 `&'static` 可以被强转成一个较短的生命周期 4. `&'static` 可以被强转成一个较短的生命周期
**Example** **Example**
```rust,editable ```rust,editable
@ -103,7 +103,7 @@ fn main() {
关于 `'static` 的特征约束详细解释,请参见 [Rust 语言圣经](https://course.rs/advance/lifetime/static.html#t-static),这里就不再赘述。 关于 `'static` 的特征约束详细解释,请参见 [Rust 语言圣经](https://course.rs/advance/lifetime/static.html#t-static),这里就不再赘述。
5🌟🌟 5. 🌟🌟
```rust,editable ```rust,editable
/* 让代码工作 */ /* 让代码工作 */
use std::fmt::Debug; use std::fmt::Debug;
@ -137,7 +137,7 @@ fn main() {
``` ```
6🌟🌟🌟 6. 🌟🌟🌟
```rust,editable ```rust,editable
use std::fmt::Display; use std::fmt::Display;