Difference between revisions of "Rust-Programming-Language/C2/Iterators-and-Closures/English"
| Line 1: | Line 1: | ||
| + | |||
{| border="1" | {| border="1" | ||
|- | |- | ||
| Line 5: | Line 6: | ||
|- | |- | ||
|| '''Slide 1''' | || '''Slide 1''' | ||
| − | || Welcome to the Spoken Tutorial on '''Iterators and Closures''' in''' Rust | + | |
| − | |- | + | '''Title Slide''' |
| + | || Welcome to the Spoken Tutorial on '''Iterators and Closures''' in''' Rust'''. | ||
| + | |- | ||
|| '''Slide 2''' | || '''Slide 2''' | ||
'''Learning Objectives''' | '''Learning Objectives''' | ||
|| In this tutorial, we will learn about: | || In this tutorial, we will learn about: | ||
| − | * | + | * Iterators |
| − | * | + | * Types of Iterators and |
| − | * | + | * Closures |
| − | |- | + | |- |
|| '''Slide 3''' | || '''Slide 3''' | ||
| Line 23: | Line 26: | ||
|| To record this tutorial I’m using the following setup. | || To record this tutorial I’m using the following setup. | ||
| − | |- | + | |- |
| − | || '''Slide | + | || '''Slide 4''' |
'''Code Files''' | '''Code Files''' | ||
| + | |||
| + | * iterators.rs | ||
|| | || | ||
| − | * | + | * The following code file is required to practise this tutorial. |
| − | + | ||
| − | + | ||
| − | |- | + | * This file is provided in the Code Files link of this tutorial page. |
| − | || '''Slide | + | |
| + | |- | ||
| + | || '''Slide 5''' | ||
'''Iterators''' | '''Iterators''' | ||
|| Let us get started. | || Let us get started. | ||
| − | |||
| − | |||
| − | |||
| − | + | * Iterators are powerful and flexible tools. | |
| − | || '''Slide 7 | + | * They process sequences of data one at a time. |
| + | * They help to iterate over a collection of values such as arrays, vectors, maps, etc. | ||
| + | |||
| + | |- | ||
| + | || '''Slide 6 + 7''' | ||
'''Type of Iterators''' | '''Type of Iterators''' | ||
|| In Rust we can categorize iterators into 3 main types. | || In Rust we can categorize iterators into 3 main types. | ||
| − | * | + | * '''Basic & Range Iterators ''' |
| − | * | + | * '''Iterator Adapters ''' and |
| − | * | + | * '''Iterator Consumers/Collectors''' |
| − | |- | + | |- |
|| | || | ||
| − | || | + | || Let’s learn about '''Basic and Range Iterators''' with an example. |
| − | + | |- | |
| − | Let’s learn about '''Basic and Range Iterators''' with an example. | + | |
| − | |- | + | |
|| Open '''Visual''' '''code editor''' | || Open '''Visual''' '''code editor''' | ||
|| Open the '''Visual Studio code editor.''' | || Open the '''Visual Studio code editor.''' | ||
| − | |- | + | |- |
|| In the menu bar, click on '''Terminal''' and select''' New Terminal'''. | || In the menu bar, click on '''Terminal''' and select''' New Terminal'''. | ||
| − | |||
|| In the menu bar, click on '''Terminal''' and select''' New Terminal'''. | || In the menu bar, click on '''Terminal''' and select''' New Terminal'''. | ||
| − | |- | + | |- |
|| I have created the '''filehandling''' project as explained earlier. | || I have created the '''filehandling''' project as explained earlier. | ||
|| Let us go to our working directory '''MyRustProject''' as explained earlier. | || Let us go to our working directory '''MyRustProject''' as explained earlier. | ||
| Line 73: | Line 76: | ||
Open the created project as shown. | Open the created project as shown. | ||
| − | |- | + | |- |
|| Point to the '''main.rs''' file. | || Point to the '''main.rs''' file. | ||
| − | + | || In the '''main.rs '''file, copy and paste the code from the Code file. | |
| − | || | + | |- |
| − | |- | + | |
|| fn main() { | || fn main() { | ||
| Line 104: | Line 106: | ||
Save the program. | Save the program. | ||
| − | |- | + | |- |
|| | || | ||
|| Run the code to see the output. | || Run the code to see the output. | ||
| − | |- | + | |- |
|| | || | ||
|| Let’s see an example of commonly used '''iterator adapters'''. | || Let’s see an example of commonly used '''iterator adapters'''. | ||
| Line 114: | Line 116: | ||
Copy paste the code from the code file. | Copy paste the code from the code file. | ||
| − | |- | + | |- |
|| fn main() { | || fn main() { | ||
| Line 136: | Line 138: | ||
It gives us '''immutable references''' to each element in the vector. | It gives us '''immutable references''' to each element in the vector. | ||
| − | '''.map() '''method uses a '''closure''' that takes each element x and returns | + | '''.map() '''method uses a '''closure''' that takes each element x and returns its square. |
| − | This doesn't immediately compute the | + | This doesn't immediately compute the square. |
It builds a new iterator pipeline that knows how to compute them when needed. | It builds a new iterator pipeline that knows how to compute them when needed. | ||
| − | Finally, '''.collect() '''consumes the iterator and gathers the squares into a | + | Finally, '''.collect() ''' method consumes the iterator and gathers the squares into a new vector |
| − | |- | + | |- |
|| | || | ||
|| Run the code to see the output. | || Run the code to see the output. | ||
| − | The result is printed as a | + | The result is printed as a new vector [1, 4, 9, 16, 25] |
| − | |- | + | |- |
|| | || | ||
|| Let’s see an example of '''Iterator Consumers '''or''' Collectors.''' | || Let’s see an example of '''Iterator Consumers '''or''' Collectors.''' | ||
| − | These methods consume an iterator and return results like '''Vec, bool''', or a single value. | + | These methods consume an iterator and return results like '''Vec''', '''bool''', or a single value. |
| − | |- | + | |- |
|| | || | ||
|| Copy and paste the code from the code file. | || Copy and paste the code from the code file. | ||
| − | |- | + | |- |
|| fn main() { | || fn main() { | ||
| Line 175: | Line 177: | ||
} | } | ||
| − | || This program shows how to use '''iterators '''with filters to show only even numbers from a vector. | + | || This program shows how to use '''iterators ''' with filters to show only even numbers from a vector. |
Filter() method which takes a closure that returns true or false for each element. | Filter() method which takes a closure that returns true or false for each element. | ||
| − | The condition that | + | The condition that we have used here will check if the number is even or not. |
Only the elements that satisfy this condition are passed forward in the iterator pipeline. | Only the elements that satisfy this condition are passed forward in the iterator pipeline. | ||
| − | Lastly, .collect() method gathers the remaining elements into new '''vector evens'''. | + | Lastly, '''.collect()''' method gathers the remaining elements into new '''vector evens'''. |
Save the program. | Save the program. | ||
| − | |- | + | |- |
|| | || | ||
|| In the terminal, type '''cargo run '''and see the output. | || In the terminal, type '''cargo run '''and see the output. | ||
The result is [2, 4, 6], it contains only even numbers from the original list. | The result is [2, 4, 6], it contains only even numbers from the original list. | ||
| − | |- | + | |- |
| − | + | ||
| − | + | || '''Slide 8''' | |
| − | + | ||
| − | || '''Slide | + | |
'''Closures''' | '''Closures''' | ||
| − | * | + | * In Rust, closure is a function without names |
| − | * | + | * It can capture variables from its environment, which is a key difference from regular functions. |
|| Next we will see about '''Closures'''. | || Next we will see about '''Closures'''. | ||
| − | * | + | * Closure is a function without names |
| − | * | + | * It can capture variables from its environment, which is a key difference from regular functions. |
| − | |- | + | |- |
|| | || | ||
|| Let us understand '''closures''' with an example. | || Let us understand '''closures''' with an example. | ||
| Line 212: | Line 212: | ||
Clear the window and copy and paste the code from the codefile. | Clear the window and copy and paste the code from the codefile. | ||
| − | |- | + | |- |
|| fn main() { | || fn main() { | ||
| Line 226: | Line 226: | ||
'''}''' | '''}''' | ||
| − | || Here, parameters are placed between '''vertical | + | || Here, parameters are placed between '''vertical pipelines'''. |
| − | + | We have defined a closure and binded it to the '''add_one''' variable. | |
| − | + | We then call the closure with '''add_one(2)''' and bind the return value to the '''result''' variable. | |
| − | '''Closures '''can omit''' type annotations '''and '''return types''', as Rust is capable of '''type inference''' | + | '''Closures ''' can omit''' type annotations '''and '''return types''', as Rust is capable of '''type inference''' |
Save the program. | Save the program. | ||
| − | |- | + | |- |
|| | || | ||
|| Run the code to see the output. | || Run the code to see the output. | ||
| − | |- | + | |- |
|| | || | ||
| − | || | + | || Let us see another example for multiple statements inside a closure. |
| − | |- | + | |- |
|| | || | ||
|| Clear the previous code. Copy paste the code from the code file. | || Clear the previous code. Copy paste the code from the code file. | ||
| − | |- | + | |- |
|| fn main() { | || fn main() { | ||
| Line 278: | Line 278: | ||
Save the program. | Save the program. | ||
| − | |- | + | |- |
|| | || | ||
|| In the terminal, type '''cargo run.''' | || In the terminal, type '''cargo run.''' | ||
| Line 285: | Line 285: | ||
That is the sum of 5 and 3 is 8. The squared value is 64. | That is the sum of 5 and 3 is 8. The squared value is 64. | ||
| − | |- | + | |- |
| − | || | + | || '''Slide 9''' |
| + | |||
| + | '''Summary''' | ||
|| This brings us to the end of this tutorial. | || This brings us to the end of this tutorial. | ||
Let us summarize. | Let us summarize. | ||
| − | |- | + | |- |
| − | || Slide | + | ||'''Slide 10 + 11''' |
| − | * | + | |
| + | '''Assignment''' | ||
| + | |||
| + | * Write a Rust program that takes a vector of integers: | ||
let numbers = vec![10, 15, 20, 25, 30, 35, 40]; | let numbers = vec![10, 15, 20, 25, 30, 35, 40]; | ||
| − | * | + | * Using iterators, perform the following steps: |
| − | ** | + | ** Filter out the numbers that are divisible by 10 |
| − | ** | + | ** Collect the result into a new vector. |
| − | ** | + | ** Finally, print the resulting vector. |
|| As an assignment, | || As an assignment, | ||
| − | * | + | * Write a Rust program that takes a vector of integers: |
| − | * | + | * Using iterators, perform the following steps: |
| + | |||
| + | |- | ||
| + | || '''Slide 12''' | ||
| − | + | '''Thank You''' | |
| − | + | ||
|| Thanks for joining. | || Thanks for joining. | ||
|- | |- | ||
|} | |} | ||
| − | |||
Latest revision as of 13:13, 21 October 2025
| Visual Cue | Narration |
| Slide 1
Title Slide |
Welcome to the Spoken Tutorial on Iterators and Closures in Rust. |
| Slide 2
Learning Objectives |
In this tutorial, we will learn about:
|
| Slide 3
System Requirements To record this tutorial I’m using |
To record this tutorial I’m using the following setup. |
| Slide 4
Code Files
|
|
| Slide 5
Iterators |
Let us get started.
|
| Slide 6 + 7
Type of Iterators |
In Rust we can categorize iterators into 3 main types.
|
| Let’s learn about Basic and Range Iterators with an example. | |
| Open Visual code editor | Open the Visual Studio code editor. |
| In the menu bar, click on Terminal and select New Terminal. | In the menu bar, click on Terminal and select New Terminal. |
| I have created the filehandling project as explained earlier. | Let us go to our working directory MyRustProject as explained earlier.
Type the command cargo new iterators and press Enter. Open the created project as shown. |
| Point to the main.rs file. | In the main.rs file, copy and paste the code from the Code file. |
| fn main() {
let numbers = vec![1, 2, 3]; let mut iter = numbers.iter(); println!("{:?}", iter.next()); // Some(1) println!("{:?}", iter.next()); // Some(2) println!("{:?}", iter.next()); // Some(3) println!("{:?}", iter.next()); // None } |
We declared a vector called numbers with values 1, 2, 3.
numbers.iter() method creates an iterator named iter. iterator can safely access vector elements without looping. next() method is used to traverse through the items. It returns a value None when it reaches the end of the collection. Save the program. |
| Run the code to see the output. | |
| Let’s see an example of commonly used iterator adapters.
Clear the previous code. Copy paste the code from the code file. | |
| fn main() {
let numbers = vec![1, 2, 3, 4, 5]; let squared: Vec<i32> = numbers .iter() .map(|x| x * x) .collect(); println!("{:?}", squared); // [1, 4, 9, 16, 25] } |
We declare a vector of integers.
We then create an iterator using the .iter() method. It gives us immutable references to each element in the vector. .map() method uses a closure that takes each element x and returns its square. This doesn't immediately compute the square. It builds a new iterator pipeline that knows how to compute them when needed. Finally, .collect() method consumes the iterator and gathers the squares into a new vector |
| Run the code to see the output.
The result is printed as a new vector [1, 4, 9, 16, 25] | |
| Let’s see an example of Iterator Consumers or Collectors.
These methods consume an iterator and return results like Vec, bool, or a single value. | |
| Copy and paste the code from the code file. | |
| fn main() {
let numbers = vec![1, 2, 3, 4, 5, 6]; let evens: Vec<_> = numbers .iter() .filter(|x| *x % 2 == 0) .collect();
} |
This program shows how to use iterators with filters to show only even numbers from a vector.
Filter() method which takes a closure that returns true or false for each element. The condition that we have used here will check if the number is even or not. Only the elements that satisfy this condition are passed forward in the iterator pipeline. Lastly, .collect() method gathers the remaining elements into new vector evens. Save the program. |
| In the terminal, type cargo run and see the output.
The result is [2, 4, 6], it contains only even numbers from the original list. | |
| Slide 8
Closures
|
Next we will see about Closures.
|
| Let us understand closures with an example.
Switch back to the visual code editor. Clear the window and copy and paste the code from the codefile. | |
| fn main() {
// define a closure and store it in a variable let add_one = |x: i32| x + 1; // call closure and store the result in a variable let result = add_one(2); println!("Result = {}", result); } |
Here, parameters are placed between vertical pipelines.
We have defined a closure and binded it to the add_one variable. We then call the closure with add_one(2) and bind the return value to the result variable. Closures can omit type annotations and return types, as Rust is capable of type inference Save the program. |
| Run the code to see the output. | |
| Let us see another example for multiple statements inside a closure. | |
| Clear the previous code. Copy paste the code from the code file. | |
| fn main() {
// define a multi-line closure let squared_sum = |x: i32, y: i32| { // find the sum of two parameters let mut sum: i32 = x + y; // find the squared value of the sum let mut result: i32 = sum * sum; return result; }; // call the closure let result = squared_sum(5, 3); println!("Result = {}", result); } |
In this example, we enclose the multiple statements using curly braces {}.
First we calculate the sum of two parameters. Then we find the squared value of the sum. Save the program. |
| In the terminal, type cargo run.
We can see the output as 64. That is the sum of 5 and 3 is 8. The squared value is 64. | |
| Slide 9
Summary |
This brings us to the end of this tutorial.
Let us summarize. |
| Slide 10 + 11
Assignment
let numbers = vec![10, 15, 20, 25, 30, 35, 40];
|
As an assignment,
|
| Slide 12
Thank You |
Thanks for joining. |