Edited the closures.md
This commit is contained in:
parent
eb00e97b2a
commit
fddd429a86
|
@ -1,5 +1,5 @@
|
||||||
# Closure
|
# Closure
|
||||||
Closures can capture the enclosing evironments. For example we can capture the `x` variable :
|
Closures can capture the enclosing environments. For example we can capture the `x` variable :
|
||||||
```rust
|
```rust
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = 1;
|
let x = 1;
|
||||||
|
@ -37,13 +37,13 @@ fn main() {
|
||||||
|
|
||||||
## Capturing
|
## Capturing
|
||||||
Closures can capture variables by borrowing or moving. But they prefer to capture by borrowing and only go lower when required:
|
Closures can capture variables by borrowing or moving. But they prefer to capture by borrowing and only go lower when required:
|
||||||
- by reference: `&T`
|
- By reference: `&T`
|
||||||
- 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 amount of changes*/
|
||||||
fn main() {
|
fn main() {
|
||||||
let color = String::from("green");
|
let color = String::from("green");
|
||||||
|
|
||||||
|
@ -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,14 +132,14 @@ 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;
|
||||||
|
|
||||||
let s = example_closure(String::from("hello"));
|
let s = example_closure(String::from("hello"));
|
||||||
|
|
||||||
/* Make it work, only changeg the following line */
|
/* Make it work, only change the following line */
|
||||||
let n = example_closure(5);
|
let n = example_closure(5);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -151,9 +151,9 @@ 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 changing the trait bound, in two ways*/
|
||||||
fn fn_once<F>(func: F)
|
fn fn_once<F>(func: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(usize) -> bool,
|
F: FnOnce(usize) -> bool,
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
move closures may still implement `Fn` or `FnMut`, even though they capture variables by move. This is because the traits implemented by a closure type are determined by what the closure does with captured values, not how it captures them. The `move` keyword only specifies the latter.
|
Move closures may still implement `Fn` or `FnMut`, even though they capture variables by move. This is because the traits implemented by a closure type are determined by what the closure does with captured values, not how it captures them. The `move` keyword only specifies the latter.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -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() {
|
||||||
|
@ -303,9 +303,9 @@ 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 can be used as arguments, you might wonder can we use functions as arguments too? And indeed we can.
|
||||||
|
|
||||||
9γππ
|
9.ππ
|
||||||
```rust,editable
|
```rust,editable
|
||||||
|
|
||||||
/* Implement `call_me` to make it work */
|
/* Implement `call_me` to make it work */
|
||||||
|
@ -326,16 +326,16 @@ 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 have thought of.
|
||||||
|
|
||||||
10γππ
|
10.ππ
|
||||||
```rust,editable
|
```rust,editable
|
||||||
/* Fill in the blank using two approches,
|
/* Fill in the blank using two aproaches,
|
||||||
and fix the errror */
|
and fix the errror */
|
||||||
fn create_fn() -> __ {
|
fn create_fn() -> __ {
|
||||||
let num = 5;
|
let num = 5;
|
||||||
|
|
||||||
// how does the following closure capture the evironment variable `num`
|
// How does the following closure capture the environment variable `num`
|
||||||
// &T, &mut T, T ?
|
// &T, &mut T, T ?
|
||||||
|x| x + num
|
|x| x + num
|
||||||
}
|
}
|
||||||
|
@ -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) -> __ {
|
||||||
|
|
Loadingβ¦
Reference in New Issue