Merge pull request #336 from Tanish-Eagle/functional-editing

Functional editing
This commit is contained in:
Sunface
2022-12-07 08:39:11 +08:00
committed by GitHub
2 changed files with 47 additions and 47 deletions

View File

@ -1,5 +1,5 @@
# 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
fn main() {
let x = 1;
@ -37,13 +37,13 @@ fn main() {
## Capturing
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 mutable reference: `&mut T`
- by value: `T`
- By reference: `&T`
- By mutable reference: `&mut T`
- By value: `T`
1🌟
1.🌟
```rust,editable
/* Make it work with least changing */
/* Make it work with least amount of changes*/
fn main() {
let color = String::from("green");
@ -60,7 +60,7 @@ fn main() {
}
```
2🌟🌟
2.🌟🌟
```rust,editable
/* Make it work
- Dont use `_reborrow` and `_count_reborrowed`
@ -89,7 +89,7 @@ fn main() {
}
```
3🌟🌟
3.🌟🌟
```rust,editable
/* 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 ;
```
4🌟
4.🌟
```rust,editable
fn main() {
let example_closure = |x| x;
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);
}
```
@ -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)
- FnOnce: the closure uses the captured value by value (T)
5🌟🌟
5.🌟🌟
```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)
where
F: FnOnce(usize) -> bool,
@ -168,7 +168,7 @@ fn main() {
}
```
6 🌟🌟
6. 🌟🌟
```rust,editable
fn main() {
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.
7🌟🌟
7.🌟🌟
```rust,editable
/* 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
fn main() {
@ -285,7 +285,7 @@ fn exec<F: Fn()>(f: F) {
}
```
8🌟🌟
8.🌟🌟
```rust,editable
/* Fill in the blank */
fn main() {
@ -303,9 +303,9 @@ fn exec<'a, F: __>(mut f: F) {
## 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
/* Implement `call_me` to make it work */
@ -326,16 +326,16 @@ fn main() {
```
## 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
/* Fill in the blank using two approches,
/* Fill in the blank using two aproaches,
and fix the errror */
fn create_fn() -> __ {
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 ?
|x| x + num
}
@ -347,7 +347,7 @@ fn main() {
}
```
11🌟🌟
11.🌟🌟
```rust,editable
/* Fill in the blank and fix the error*/
fn factory(x:i32) -> __ {

View File

@ -11,7 +11,7 @@ fn main() {
}
```
In above code, You may consider `for` as a simple loop, but actually it is iterating over a iterator.
In the code above, You may consider `for` as a simple loop, but actually it is iterating over a iterator.
By default `for` will apply the `into_iter` to the collection, and change it into a iterator. As a result, the following code is equivalent to previous one:
```rust
@ -23,18 +23,18 @@ fn main() {
}
```
1🌟
1.🌟
```rust,editable
/* Refactoring the following code using iterators */
fn main() {
let arr = [0; 10];
for i in 0..arr.len() {
println!("{}",arr[i])
println!("{}",arr[i]);
}
}
```
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
/* Fill in the blank */
fn main() {
@ -55,13 +55,13 @@ pub trait Iterator {
fn next(&mut self) -> Option<Self::Item>;
// methods with default implementations elided
// Methods with default implementations elided
}
```
And we can call the `next` method on iterators directly.
3🌟🌟
3.🌟🌟
```rust,editable
/* Fill the blanks and fix the errors.
Using two ways if possible */
@ -75,28 +75,28 @@ fn main() {
```
## into_iter, iter and iter_mut
In the previous section, we have mentioned that `for` will apply the `into_iter` to the collection, and change it into a iterator.However, this is not the only way to convert collections into iterators.
In the previous section, we have mentioned that `for` will apply the `into_iter` to the collection, and change it into a iterator. However, this is not the only way to convert collections into iterators.
`into_iter`, `iter`, `iter_mut`, all of them can convert an collection into iterator, but in different ways.
`into_iter`, `iter`, `iter_mut`, all of them can convert a collection into iterator, but in different ways.
- `into_iter` cosumes the collection, once the collection has been comsumed, it is no longer available for reuse, because its ownership has been moved within the loop.
- `into_iter` consumes the collection, once the collection has been consumed, it is no longer available for reuse, because its ownership has been moved within 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.
4🌟
4.🌟
```rust,editable
/* Make it work */
fn main() {
let arr = vec![0; 10];
for i in arr {
println!("{}", i)
println!("{}", i);
}
println!("{:?}",arr);
}
```
5🌟
5.🌟
```rust,editable
/* Fill in the blank */
fn main() {
@ -113,7 +113,7 @@ fn main() {
}
```
6🌟🌟
6.🌟🌟
```rust,editable
/* Fill in the blank */
fn main() {
@ -130,7 +130,7 @@ fn main() {
## Creating our own iterator
We can not only create iterators from collections types, but also can create iterators by implementing the `Iterator` trait on our own types.
We can not only create iterators from collection's types, but also can create iterators by implementing the `Iterator` trait on our own types.
**Example**
```rust
@ -169,7 +169,7 @@ fn main() {
}
```
7🌟🌟🌟
7.🌟🌟🌟
```rust,editable
struct Fibonacci {
curr: u32,
@ -208,8 +208,8 @@ The `Iterator` trait has a number of methods with default implementations provid
### Consuming adaptors
Some of these methods call the method `next`to use up the iterator, so they are called *consuming adaptors*.
8🌟🌟
```rust,edtiable
8.🌟🌟
```rust,editable
/* Fill in the blank and fix the errors */
fn main() {
let v1 = vec![1, 2, 3];
@ -226,10 +226,10 @@ fn main() {
```
#### collect
Other than converting a collection into an iterator, we can also `collect` the result values into a collection, `collect` will cosume the iterator.
#### Collect
Other than converting a collection into an iterator, we can also `collect` the result values into a collection, `collect` will consume the iterator.
9🌟🌟
9.🌟🌟
```rust,editable
/* Make it work */
use std::collections::HashMap;
@ -251,9 +251,9 @@ fn main() {
### Iterator adaptors
Methods allowing you to change one iterator into another iterator are known as *iterator adaptors*. You can chain multiple iterator adaptors to perform complex actions in a readable way.
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 adapters to get results from calls to iterator adapters.
10🌟🌟
10.🌟🌟
```rust,editable
/* Fill in the blanks */
fn main() {
@ -265,7 +265,7 @@ fn main() {
}
```
11🌟🌟
11.🌟🌟
```rust
/* Fill in the blanks */
use std::collections::HashMap;
@ -281,7 +281,7 @@ fn main() {
#### Using closures in iterator adaptors
12🌟🌟
12.🌟🌟
```rust
/* Fill in the blanks */
#[derive(PartialEq, Debug)]