0% found this document useful (0 votes)
4 views

Rust Lectures2

The document provides an introduction to the Rust programming language, covering its history, key features such as safety, performance, and concurrency, as well as the setup of the Rust environment using tools like `rustup` and `cargo`. It also details data types, variables, and input/output operations in Rust, along with examples and exercises to reinforce learning. The document emphasizes the importance of error handling and best practices in coding with Rust.

Uploaded by

saif.basheer
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Rust Lectures2

The document provides an introduction to the Rust programming language, covering its history, key features such as safety, performance, and concurrency, as well as the setup of the Rust environment using tools like `rustup` and `cargo`. It also details data types, variables, and input/output operations in Rust, along with examples and exercises to reinforce learning. The document emphasizes the importance of error handling and best practices in coding with Rust.

Uploaded by

saif.basheer
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 54

.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.

=======================================================================================================

### Lecture 1: Introduction to Rust ###

### **History of Rust**

- **Initiation (2006)**:
Rust was first conceived by Mozilla Research with the goal of creating a
systems programming language that would offer both performance and safety.

- **First Release (2010)**:


The first publicly available version of Rust, version 0.1, was released.

- **Stability Focus (2012-2015)**:


After several iterations, Rust 1.0 was released in May 2015, marking a
significant milestone with its focus on stability and backwards
compatibility.

- **Continuous Evolution**:
Since then, Rust has seen numerous updates, adding features like async/await
(Rust 1.39), improved borrow checker diagnostics, and more, solidifying its
position in the programming landscape.

### **Key Features**

#### **1. Safety**

- **Memory Safety**:
Rust's ownership model and borrow checker ensure memory safety at compile
time, preventing null or dangling pointers.

- **Data Race Prevention**:


Compile-time checks for concurrent access to data prevent data races.

- **Error Handling**:
Strong focus on explicit error handling through `Result` and `?`,
encouraging robust code.

01
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

#### **2. Performance**

- **Compiled Language**:
Rust code is compiled to machine code, providing performance similar to C
and C++.

- **Zero-Cost Abstractions**:
High-level abstractions without runtime overhead, thanks to its compilation
model.

- **Direct Hardware Manipulation**:


Allows for direct access to hardware resources when needed.

#### **3. Concurrency**

- **High-Level Concurrency Primitives**:


Channels, mutexes, and more are provided in the standard library.
- **Async/Await Support (since Rust 1.39)**:
Simplifies writing asynchronous code that’s both efficient and readable.

- **Fearless Concurrency**:
Thanks to its safety features, Rust aims to make concurrency less daunting.

### **Setting up the Rust Environment**

#### **Using `rustup` and `cargo`**

1. **Install `rustup`**:
- Go to [https://www.rust-lang.org/tools/install](https://www.rust-lang.org/
tools/install) and follow the installation instructions for your platform.
- `rustup` is the recommended toolchain installer for Rust.

2. **Verify Installation**:
- Open a new terminal or command prompt.
- Type `rustc --version` to verify the Rust compiler version.
- Type `cargo --version` to verify the package manager's version.

02
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

3. **Understanding `cargo`**:
- **Package Manager**: Manages dependencies for your projects.
- **Build System**: Compiles your project with a simple command.
- **Project Structure**: Initializes new projects with a conventional
directory structure.

### **`main.rs` File Structure**

- **New Project with `cargo`**:

```bash
cargo new hello_world

```
Navigate into the newly created project directory.
- **`main.rs` Contents (Generated by `cargo`)**:

fn main() {
println!("Hello, world!");
}

### **Compiling and Running with `cargo`**

1. **Navigate to Your Project Directory**:


```bash
cd hello_world
```
2. **Build the Project** (Implicitly done when running):
- Optionally, to just build without running: `cargo build`
3. **Run the Project**:

```bash
cargo run
```

03
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

Output: `Hello, world!`

### **Example Walkthrough**


- **Step-by-Step Explanation of `main.rs`**:
- `fn main() { ... }`: Declares the entry point of your program.
- `println!("Hello, world!");`: Prints the provided text to the console
followed by a newline. The `!` invokes the macro expansion for `println`.

### **Experimentation and Learning Tips**

- **Modify the `main.rs`**:


Try changing the printed message and see the result with `cargo run`.

- **Read Documentation**:
[https://doc.rust-lang.org/](https://doc.rust-lang.org/) is an invaluable
resource.

- **Practice with Rust by Example**:


[https://doc.rust-lang.org/rust-by-example/](https://doc.rust-lang.org/rust-
by-example/)

- **Join the Community**:


Participate in forums like[users.rust-lang.org](https://users.rustlang.org/)
for questions and discussions.

**Lecture Conclusion**
- You've now set up a Rust development environment.
- Successfully compiled and ran your first Rust program, "Hello, World!".
- Understand the foundational aspects of Rust: Safety, Performance, and
Concurrency.
.

**Homework/Next Steps**
- Dive deeper into Rust’s safety features with tutorials on ownership and
borrowing.
- Experiment with simple command-line tools using `cargo` and Rust.
- Explore projects on [crates.io](https://crates.io/) to see how dependencies
are managed in real-world projects.

04
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* **Exercises**:
1. Modify the "Hello, World!" program to print your name.
2. Explore the Rust documentation for more `println!` macros.

### Lecture 2: Data Types and Variables ###

### **Programming Basics: Data Types**

#### **Introduction to Data Types**


In programming, a **data type** is a classification of data based on its
format, size, and set of values it can hold. Understanding data types is
crucial for writing efficient, bug-free code. Here are the fundamental data
types found in most programming languages:

1. **Integers**:
Whole numbers, either positive, negative, or zero (e.g., `-5`, `0`, `123`).

2. **Floating Point Numbers (Floats)**:


Decimal numbers (e.g., `-5.5`,`3.14159`).

3. **Booleans**:
Logical values representing true or false.

4. **Characters**:
Single symbols, such as letters, digits, or special characters (e.g., `'a'`,
`'1'`, `'!'`).

#### **Type Systems: Statically vs Dynamically Typed**

Programming languages are categorized based on their type systems:

* **Statically Typed Languages**:


+ Data types are known at **compile time**.
+ Type checking occurs before the code is executed, preventing type-
related errors at runtime.
+ Examples: Rust, C, C++, Go

05
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* **Dynamically Typed Languages**:


+ Data types are determined at **runtime**.
+ More flexible, but may lead to type errors during execution if not
managed properly.
+ Examples: Python, JavaScript, Ruby

### **Rust Data Types**

#### **Scalars**

Scalars are single values. Rust's scalar types include:

1. **Integers (`i32`, `u8`, etc.)**:


* Signed (can be negative): `i8`, `i16`, `i32` (default), `i64`, `i128`
* Unsigned (always non-negative): `u8`, `u16`, `u32`, `u64`, `u128`

2. **Floating Point Numbers (`f32`, `f64`)**:


* `f32` (single precision, 32 bits)
* `f64` (double precision, 64 bits, default)

3. **Booleans (`bool`)**:
* Can be either `true` or `false`
4. **Characters (`char`)**:
* Represented as Unicode scalar values (e.g., `'a'`, `' 👍'`)
#### **Compound Types**
Compound types group multiple values into one.

1. **Tuples**:
* Fixed length, heterogeneous (can contain different data types).
* Defined using parentheses `()`.
* Example: `(i32, f64, char)`

2. **Arrays**:
* Fixed length, homogeneous (all elements must have the same data type).
* Defined using square brackets `[]`.
* Example: `[i32; 5]` (an array of 5 `i32` values)

06
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================
h

### **Example: Using Rust Data Types**

fn main()
{
// Scalars
let signed_int: i32 = -20;
let unsigned_int: u8 = 255;
let pi: f64 = 3.141592653589793; // Default is f64 for float literals
let isAdmin: bool = true;
let smiley: char = ' '; 👍
// Compound Types
let person: (String, i32, f64) = (
String::from("John Doe"),
30,
1.83 // Height in meters
);

println!("Name: {}", person.0);


println!("Age: {}", person.1);
println!("Height: {} m", person.2);

let scores: [i32; 3] = [90, 80, 70];


println!("Average score (manual calc): {}", (scores[0] + scores[1] +
scores[2]) / 3);
}
### **Variables in Rust**

* **Declaration**:
Use the `let` keyword.
* **Immutability by Default**:
Variables are immutable unless explicitly made mutable with `mut`.

* **Type Inference**:
Rust can often infer the type of a variable from its initial value, but
explicit types are recommended for clarity and safety.

// Immutable variable (default)


let name = "Alice";

07
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

// Mutable variable
let mut age = 25;
age = 30; // This is allowed because 'age' is mutable

// Explicit type annotation


let name: String = "Bob".to_string();

### **Key Takeaways**


* Understand the basic data types (integers, floats, booleans, characters)
and their significance in programming.
* Familiarize yourself with Rust's scalar (integer, float, boolean,
character) and compound (tuples, arrays) data types.
* Know how to declare variables in Rust, including understanding
immutability by default and the role of type inference.

### **Exercises**

1. **Data Type Identification**:


* Identify the data types of each value in the following list: `5`, `-3.14`,
`true`, `'A'`, `"Hello"`.
2. **Rust Type Specification**:
* Write Rust code to declare variables for an integer, a floating-point
number, and a boolean, specifying their types explicitly.

3. **Compound Types Practice**:


* Create a tuple in Rust containing a string, an integer, and a float. Print
out each element of the tuple.

### Lecture 3: Input/Output Instructions ###

### **Programming Basics: I/O Operations**

#### **Importance of User Input**

* **Interactivity**:
Allows programs to respond differently based on user actions or data.

08
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* **Customization**:
Enhances user experience by enabling personalized interactions.

* **Data Collection**:
Crucial for gathering information from users, which can be processed or stored.

* **Dynamic Behavior**:
Programs can adapt their behavior based on input, making them more
versatile.

#### **Basic Output Operations**

* **Displaying Text/Messages**:
Informing the user about program states, results, or errors.

* **Visual Feedback**:
Enhancing user experience through intuitive visual cues (e.g., progress
bars).

* **Logging**:
Recording events for debugging, auditing, or analytics purposes.

**Common I/O Operations in Programming:**

| **Operation** | **Description** |
| --- | --- |
| `print!()` | Displays text without a newline. |
| `println!()` | Prints text followed by a newline character.|
| `input()`/`readline()` | Reads user input until a delimiter |
(usually a newline). |

### **Input in Rust**

#### **Using `std::io` for Input**


Rust's standard library, `std`, provides the `io` module for handling

09
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

input/output operations.

* **Reading from Standard Input (`stdin`)**:


+ Use `std::io::stdin()` to access the standard input stream.
+ `read_line()` method for reading a line of input into a `String`.

**Key Concepts:**

* **Buffers**:
Temporary storage for data being moved from one place to another (e.g., from
keyboard to program).

* **Error Handling**:
Crucial in I/O operations due to potential failures (e.g., invalid input,
device errors).

#### **Example: Reading User Input in Rust**

use std::io;

fn main() {
// Prompt user for their name
println!("Please enter your name:");
// Create a mutable String to store the user's input
let mut user_name = String::new();

// Attempt to read a line of input from stdin into our String


io::stdin().read_line(&mut user_name)
.expect("Failed to read line"); // Handle potential error

// Print out the user's name, trimming the newline character


println!("Hello, {}!", user_name.trim());
}

10
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================
.

**Breakdown of the Example:**

1. **Import `std::io`**:
Access Rust's input/output functionality.
2. **Prompt User**:
Inform the user what action to take using `println!`.

3. **Create a Mutable String**:


Store the user's input in a `String` that can be modified.

4. **Read Input from `stdin`**:


* Use `io::stdin()` to get a handle on the standard input stream.
* Call `read_line()` to read into our mutable `String`.

5. **Error Handling**:
Utilize `.expect()` to handle potential errors during input reading.
6. **Process and Output**:
* Trim the newline character from the input using `.trim()`.
* Greet the user by printing out their name with `println!`.

### **Best Practices for Input in Rust**


6

* **Always Handle Potential Errors**:


Use methods like `.expect()`, `.unwrap()`, or proper error handling with
`Result` to ensure robustness.

* **Validate User Input**:


Check input data for correctness and sanity to prevent unexpected behavior
or security vulnerabilities.
* **Use Meaningful Variable Names**:
Enhance code readability by choosing descriptive names for variables storing
user input.

### **Exercises**
1. **Enhanced Greeting Program**:
* Modify the example to also ask for the user's age and print out a
greeting with their name and age.
2. **Simple Calculator**:

11
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* Create a program that prompts the user for two numbers and an operation
(+, -, \*, /), then performs and displays the result.
3. **Input Validation**:
* Expand on the calculator exercise by adding input validation to ensure
the user enters valid numbers and operations.

fn main()
{
println!("Please enter your name:");

let mut name = String::new();


io::stdin().read_line(&mut name)
.expect("Failed to read line");

println!("Hello, {}!", name.trim());


}

### Lecture 4: Formatted Output ###

**Section 1: Introduction to Formatted Output in Rust**

### **The `print!` and `println!` Macros**


- **`print!`**: Prints without appending a newline.
- **`println!``: Prints and appends a newline at the end.

### **Basic Usage**

fn main()
{
print!("Hello, "); // No newline
println!("World!"); // With newline
println!("---");
print!("This is ");
print!("a test.");
}

12
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

**Output:**
Hello, World!
---
This is a test.
```
### **Placeholder Basics - `{}`**
- Use `{}` as placeholders for values.

fn main()
{
let name = "Alice";
let age = 30;
println!("My name is {} and I am {}.", name, age);
}

**Output:**
My name is Alice and I am 30.

**Section 2: Formatted Output with Loops**

### **Printing Sequences with `for` Loop**

fn main()
{
let numbers = [1, 2, 3, 4, 5];
for num in &numbers
{
println!("Number: {}", num);
}
}

**Output:**
```
Number: 1
Number: 2
Number: 3

13
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

Number: 4
Number: 5
.

### **Customizing Output with `print!` inside a Loop**

fn main()
{
let fruits = ["Apple", "Banana", "Cherry"];
for (i, fruit) in fruits.iter().enumerate()
{
print!("{}: {}, ", i+1, fruit);
}
println!(); // Newline after the loop
}

**Output:**
1: Apple, 2: Banana, 3: Cherry,

### **Precision Formatting with `{:}`**


- **Width and Precision**:
`{:width$.precision}`.
- **Padding and Alignment**:
Use `>` for right alignment, `<` for left (default), and `^` for centering.
Pad with `0` for zeros or any other character.

fn main()
{
let pi = 3.14159265359;
println!("Pi (default): {}", pi);
println!("Pi (width 5, precision 2): {:5.2}", pi);
println!("Pi (left-aligned width 5, precision 2): {:<5.2}", pi);
println!("Pi (right-aligned width 5, precision 2): {:>5.2}", pi);
println!("Pi (centered width 5, precision 2): {:^5.2}", pi);
}

14
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

**Output:**
Pi (default): 3.14159265359
Pi (width 5, precision 2): 3.14
Pi (left-aligned width 5, precision 2): 3.14
Pi (right-aligned width 5, precision 2): 3.14
Pi (centered width 5, precision 2): 3.14

### **Combining Looping with Advanced Formatting**

fn main() {
let students =
[
("John", 18, "Math"),
("Alice", 20, "Science"),
("Bob", 19, "History"),
];

println!(" {:^10} | {:^5} | {:^7}", "Name", "Age", "Subject");


println!("-------------|-------|---------");
for (name, age, subject) in &students
{
println!(" {:<10} | {:>3} | {:^7}", name, age, subject);
}
}

**Output:**

Name | Age | Subject


-----------|---------|---------
John | 18 | Science
Alice | 20 | History
Bob | 19 | Math

### Lecture 5: Conditional Statements ###

15
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

#### **What are Conditional Statements?**

* **Definition**:
Instructions that allow a program to make decisions based on conditions or
rules.

* **Purpose**:
Enable conditional execution of code blocks, enhancing program flexibility
and responsiveness.

#### **If-Else Statements**

* **Basic Structure**:
1. `if` *condition*: Execute if true
2. `else`: Optional, execute if initial condition(s) are false
3. `else if` *condition*: Additional conditions to check before reaching
the final `else` (if present)

* **Example in Pseudocode**:

```markdown
IF it_is_raining THEN
TAKE umbrella
ELSE IF it_is_sunny THEN
WEAR sunglasses
ELSE
DRESS normally
```

#### **Nested Conditionals**

* **Definition**:
Placing conditional statements inside other conditional statements.

* **Use Case**:
Handling complex, multi-layered decision-making processes.

16
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* **Example in Pseudocode**:

```markdown
IF user_is_authenticated THEN
IF user_has_admin_rights THEN
DISPLAY admin_dashboard
ELSE
DISPLAY standard_dashboard
ELSE
REDIRECT to_login_page

### **If Statements in Rust**

#### **Basic `if` Statement**


* **Syntax**:
if *condition* {
// Code to execute if condition is true
} else {
// Optional: Code to execute if condition is false
}
.

* **Example: Guessing Game**:

fn main()
{
let secret_number = 42;
let guess = 41;
if guess < secret_number
{ println!("Too small!"); }
else if guess > secret_number
{ println!("Too big!"); }
else{ println!("You win!"); }
}

#### **`if let` for Pattern Matching**

* **Purpose**: Simplify handling of complex data structures (e.g., `enum`,

17
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

`Option`) by matching patterns.


* **Syntax**:

if let *pattern* = *value* {


// Code to execute if pattern matches
} else {
// Optional: Code for non-matching cases
}
.

* **Example: Handling `Option` Type**:

fn main()
{
let maybe_number = Some(42);
if let Some(number) = maybe_number
{ println!("The number is: {}", number); }
else
{ println!("No number present."); }
}
#### **Additional Rust Features**

* **`match` for Exhaustive Matching**:


When `if let` isn't enough, use `match` to ensure all possibilities are handled.

let day = 2;
match day
{
1 => println!("Monday"),
2 => println!("Tuesday"),
_ => println!("Another day"), // `_` catches any unmatched value
}

* **Conditional Operator (`?:`)**: A concise alternative for simple if-else


situations.

let is_admin = true;


let role = if is_admin { "Admin" } else { "User" };
println!("{}", role);

18
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

// or using the conditional operator (less common in Rust):


let role = if is_admin {"Admin"} else {"User"};

### **Best Practices for Conditional Statements in Rust**

* **Keep it Concise**:
Prefer `if let` and `match` for readability.
* **Handle All Cases**:
Use `_` in `match` statements to ensure exhaustiveness.
* **Nest Conditionals Judiciously**:
Deep nesting can reduce readability; consider refactoring or using alternative
logic structures.
.

### **Exercises**

1. **Grade Checker**:
* Write a program that takes a score as input and uses conditional statements
to print out the corresponding grade (A-F).

2. **Rock, Paper, Scissors**:


* Create a game where two players' choices are compared using nested
conditionals to determine the winner.

3. **Enhanced `if let` Practice**:


* Explore Rust's `std::result` and practice using `if let` for error handling
in a simple division program.

let number = 3;
if number > 5 {
println!("condition was true");
} else {
println!("condition was false");
}
* **Nested If Statements**
+ Using `if` inside `if`
+ Best practices for readability
+ Example:

19
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

let x = 5;
if x > 10
{
if x > 20
{
println!("x is greater than 20");
}
else
{
println!("x is between 10 and 20");
}
}

* **Exercises**:
1. Implement a simple calculator with conditional statements for
operations.
2. Use `if let` to handle different conditions based on a variable's
value.
### Lecture 6: Loops in Rust Language ###

#### **Introduction to Loops**

* **Definition**:
Loops enable iterative execution of code blocks, allowing tasks to repeat under
specified conditions.

* **Why Use Loops?**:


+ **Efficiency**: Reduce code duplication for repetitive tasks.
+ **Flexibility**: Easily adjust the number of iterations as needed.
+ **Readability**: Improve code clarity by encapsulating repeating logic.

#### **Types of Loops**

1. **Infinite/Unconditional Loops**:
* Execute indefinitely until manually stopped or a break condition is met.

20
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

2. **Conditional Loops**:
* **Pre-Tested (While)**: Check the condition before each iteration.
* **Post-Tested (Do-While)**: Execute at least once, then check the
condition.

3. **Counter/For Loops**:
* Iterate over a sequence (e.g., arrays, ranges) or collections.

### **Loops in Rust**

#### `loop` (Infinite Loop)**

* **Syntax**:

```rust
loop {
// Code to execute indefinitely
} ```

* **Exiting the Loop**:


+ `break;` - Exit the loop entirely.
+ `continue;` - Skip the rest of this iteration, moving to the next one.

* **Example: Simple Server Loop**:

fn main()
{
loop
{
println!("Server is running...");
// Simulate some work
std::thread::sleep(std::time::Duration::from_secs(2));
}
}

#### `while` Loop (Pre-Tested Conditional Loop)**

21
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* **Syntax**:

```rust
while *condition* {
// Code to execute while condition is true
}
```

* **Example: Guessing Game with Limited Attempts**:

fn main()
{
let secret_number = 42;
let mut attempts = 0;
let max_attempts = 3;

while attempts < max_attempts


{
println!("Guess the number (attempt {}):", attempts + 1);
// Simulate input and comparison for brevity
attempts += 1;
if attempts == max_attempts
{
println!("Out of attempts! The number was {}", secret_number);
}

22
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

}
}
#### `for` Loop (Counter/Iterator-Based Loop)**
* **Syntax ( Iterator-Based )**:
```rust
for *pattern* in *iterator* {
// Code to execute for each item
}
```
* **Example: Iterating Over an Array**:

fn main()
{
let numbers = [1, 2, 3, 4, 5];

for num in &numbers


{
println!("Number: {}", num);
}
}
* **Range-Based `for` Loop (Counter)**:
```rust
for *variable* in *start*..=*end* {
// Code to execute for the range
}
```

* **Example: Printing Numbers 1 Through 5**:

fn main()
{
for i in 1..=5
{
println!("Number: {}", i);
}
}

23
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

#### **Additional Rust Loop Features**

* **`loop` with Labels**: Allow `break` and `continue` to target outer loops.
```rust
'outer_loop: loop {
loop {
break 'outer_loop; // Exits the outer loop
}
}
```
* **`while let` for Conditional Loops with Pattern Matching**:

let mut numbers = vec![1, 2, 3];


while let Some(num) = numbers.pop() {
println!("Number: {}", num);
}

### **Best Practices for Loops in Rust**

* **Choose the Right Loop**:


`loop` for infinite tasks, `while` for conditional repetitions, and `for`
for iterations over collections or ranges.
* **Label Loops for Clarity**:
Especially when using nested loops with `break` or `continue`.
* **Avoid Infinite Loops Without Escape Conditions**:
Always provide a logical exit point to prevent freezing.

### **Exercises**
1. **Fibonacci Sequence**:
* Use a `while` loop to print the first 10 Fibonacci numbers.
2. **Iterator-Based Loop**:
* Create a vector of names and use a `for` loop to print each name in
uppercase.
3. **Game Development - Tic-Tac-Toe**:

24
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* Implement a simple game loop using `loop` that continues until the game is
won or drawn.

// Loop
let mut counter = 0;
loop
{
counter += 1;
if counter == 10
{
break;
}
println!("Again!");
}

// While
let mut number = 3;
while number != 0
{ println!("{}!", number);
number -= 1; }
// For
let a = [10, 20, 30, 40, 50];
for element in a.iter()
{
println!("the value is: {}", element);
}

// One more example


for i in 1..6
{
for j in 1..6
{
print!("({}.*{}) ", i, j);
}
println!();
}

25
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* **Exercises**:
1. Use `loop` to continuously ask for user input until a specific
condition.
2. Create a multiplication table using nested `for` loops.

### Lecture 7: Formatted Output Printing With Precision via Loops

### **Introduction to Nested Loops**


- Used for iterating over multiple sequences or for creating grid-like outputs.
- Combining formatted output with nested loops enhances readability and
structure.

### **Basic Example: Printing a Simple Grid**

fn main() {
for i in 1..4 { // Outer loop (Rows)
for j in 1..4 { // Inner loop (Columns)
print!("({}, {}) ", i, j);
}
println!(); // Newline after each row
}
}

26
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

**Output:**
(1, 1) (1, 2) (1, 3)
(2, 1) (2, 2) (2, 3)
(3, 1) (3, 2) (3, 3)

### **Formatted Grid with Alignment**

fn main() {
for i in 1..4
{
for j in 1..4
{
print!("{:>5}", format!("({}, {})", i, j)); // Right-aligned, width 5
}
println!();
}
}

**Output:**
(1, 1) (1, 2) (1, 3)
(2, 1) (2, 2) (2, 3)
(3, 1) (3, 2) (3, 3)

### **Printing a Multiplication Table**

fn main() {
print!(" {:>4}", ""); // Header spacing
for i in 1..10
{
print!("{:>4}", i); // Column headers
}
println!();

for i in 1..10

27
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

{
print!("{:>4}", i); // Row headers
for j in 1..10
{
print!("{:>4}", i*j);
}
println!();
}
}

**Output:**
1 2 3 4 5 6 7 8 9
1 1 2 3 4 5 6 7 8 9
2 2 4 6 8 10 12 14 16 18
3 3 6 9 12 15 18 21 24 27
4 4 8 12 16 20 24 28 32 36
5 5 10 15 20 25 30 35 40 45
6 6 12 18 24 30 36 42 48 54
7 7 14 21 28 35 42 49 56 63
8 8 16 24 32 40 48 56 64 72
9 9 18 27 36 45 54 63 72 81
### **Challenge: Nested Loop Formatted Output**
- Create a Rust program that prints a chessboard pattern using asterisks (\*)
and dots (.) in an 8x8 grid, utilizing nested loops for formatted output.
- Experiment with different placeholder formats to enhance the appearance of
your output.

**Homework/Next Steps (Updated)**


- Complete the chessboard challenge above.
- Research and implement more complex formatting options for floating-point
numbers and strings within nested loop constructs.
- Explore Rust's documentation on
[Iterator]((https://doc.rust-lang.org/std/iter/trait.Iterator.html)) to apply
iterator methods in
conjunction with formatted output.

28
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

### Lecture 8: One Dimensional Arrays (1D)

* **Overview**: Working with one-dimensional arrays in Rust.


* **One-Dimensional Arrays in Rust**:
A comprehensive guide to declaring, initializing, accessing, and modifying
elements in 1D arrays.
* **Importance of Arrays**:
Fundamental data structure for storing collections of homogeneous data
types, crucial for efficient memory management and sequential access.

### **Learning Objectives**


By the end of this lecture, you will be able to:
1. **Declare and Initialize 1D Arrays** in Rust with varying data types.
2. **Access Array Elements** using indexing.
3. **Modify Array Elements** safely and efficiently.

### **Declaring and Initializing 1D Arrays**

29
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

#### **Syntax for Declaration and Initialization**

* **Using the `[]` Syntax**:

```rust
let array_name: [data_type; size] = [initial_values];
```

* **Example with Explicit Type Annotation**:


```rust
let scores: [i32; 5] = [10, 20, 30, 40, 50];
```
* **Using the `[_; size]` Syntax for Repeated Initial Values**:
```rust
let zeros: [i32; 5] = [0; 5]; // Initializes with all zeros
```
#### **Implicit Type Annotation (Rust Infers the Type)**

* **Example Without Explicit Data Type**:


```rust
let colors = ["Red", "Green", "Blue"];
// Rust infers `colors` as [&str; 3]`
```

### **Accessing Array Elements**

#### **Indexing Syntax**

* **Access Element at Index `n`**:

```rust
array_name[n]
```
* **Example: Accessing the Second Element of `scores`**:
```rust
let second_score = scores[1]; // Returns 20

30
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

println!("Second Score: {}", second_score);


```

#### **Important Considerations**

* **Zero-Based Indexing**: The first element is at index `0`.


* **Bounds Checking**: Rust checks for out-of-bounds access at runtime,
panicking if exceeded.
+ **Example of Out-of-Bounds Access**:
```rust
println!("{}", scores[5]); // Panics! Index out of bounds
```

### **Modifying Array Elements**

#### **Assignment Syntax**

* **Modify Element at Index `n`**:

```rust
array_name[n] = new_value;
```
* **Example: Updating the Third Score**:
```rust
scores[2] = 35; // Updates the third element to 35
println!("Updated Scores: {:?}", scores);
```

#### **Mutability Requirement**

* **Arrays Must Be Declared as Mutable**


to Modify Elements:
```rust
let mut editable_scores = [10, 20, 30, 40, 50];
editable_scores[0] = 15; // Successful modification

31
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

```
* **Immutable Arrays Cannot Be Modified**:
```rust
let immutable_array = [1, 2, 3];
immutable_array[0] = 5; // Compiler Error!
```
### **Examples**

#### **1. Average of Array Elements**

* **Calculate the average of all scores in `scores` array**:

fn calculate_average(scores: &[i32]) -> f64 {


let sum: i32 = scores.iter().sum();
(*sum as f64) / (scores.len() as f64)
}
let scores = [10, 20, 30, 40, 50];
println!("Average Score: {}", calculate_average(&scores));

#### **2. Finding the Maximum Element**

* **Find and print the maximum score in `scores`**:

fn find_max(scores: &[i32]) -> i32


{
*scores.iter().max().unwrap()
}

let scores = [100, 20, 30, 400, 50];


println!("Maximum Score: {}", find_max(&scores));

### **Best Practices and Additional Tips**

* **Use Vectors Instead for Dynamic Sizes**:


Arrays have fixed sizes. For resizable collections, use `Vec<T>`.

* **Slicing for Sub-Arrays**:

32
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

Access a subset of the array using slicing (`&array_name[start..end]`).

* **Iterating Over Arrays**:


Use `.iter()`, `.iter_mut()` for iterating over immutable and mutable references
respectively.

### **Exercises**
1. **Declare an array `colors` with 3 string elements**. Access and print the
second color.

2. **Create a mutable array `numbers` of size 5, initialize with zeros, then


modify the third element to 25**.

3. **Write a function `contains_value` that checks if a given value exists


within an array**.

* **Example Code**:

fn main()
{
let scores: [i32; 5] = [10, 20, 30, 40, 50];

println!("First score: {}", scores[0]);

let mut scores_mut = [10, 20, 30, 40, 50];


scores_mut[2] = 300;
println!("Modified third score: {}", scores_mut[2]);
}

* **Exercises**:
1. Calculate the sum of all elements in an array.
2. Find the maximum value in an array.

33
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

### Lecture 9: Arrays (2D) and Vectors Introduction

* **Overview**: Exploring two-dimensional arrays & introducing vectors.


In this lecture, we will delve into the world of multi-dimensional data
structures in Rust, focusing on two-dimensional arrays. Additionally, we
will introduce vectors, a fundamental component for managing dynamic
collections in Rust. By the end of this lecture, you will be equipped to
work with 2D arrays and have a solid introduction to using vectors for
dynamic memory allocation.

### **Learning Objectives**

1. **Understand and Work with 2D Arrays**


- Declare and initialize 2D arrays in Rust
- Access and manipulate elements in 2D arrays
- Understand the use cases for 2D arrays

2. **Introduction to Vectors for Dynamic Collections**


- Understand the basics of vectors in Rust
- Create, initialize, and modify vectors

34
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

- Recognize the advantages of using vectors over fixed-size arrays

#### **Declaring and Initializing 2D Arrays**


In Rust, a 2D array is declared by specifying the size of both dimensions in
square brackets `[]` after the type, followed by the initialization values
enclosed in curly braces `{}`.

**Example: Declaring a 2D Array**

// Declaration and Initialization


let arr_2d: [[i32; 3]; 3] = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];

**Breakdown:**
- `i32`: The type of elements in the array.
- `[3]`: Specifies that each sub-array (row) will have exactly 3 elements.
- `; 3`: Indicates there are 3 rows in total.

#### **Accessing and Manipulating Elements**


Elements in a 2D array can be accessed or modified by specifying both the
row and column indices.

**Example: Accessing and Modifying Elements**

fn main()
{
let mut arr_2d: [[i32; 3]; 3] =
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// Accessing an Element

35
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

println!("Element at (1,2): {}", arr_2d[1][2]); // Outputs: 6

// Modifying an Element
arr_2d[1][2] = 10;
println!("Modified Array:");
for row in &arr_2d
{
println!("{:?}", row);
}
}

**Output:**
Element at (1,2): 6
Modified Array:
[1, 2, 3]
[4, 5, 10]
[7, 8, 9]
#### **Use Cases for 2D Arrays**

- **Game Boards:**
Representing tic-tac-toe, chess, or any game that requires a grid structure.
- **Matrix Operations:**
Useful in linear algebra for operations like matrix multiplication.
- **Fixed-Size Tables:**
When the size of the data is known beforehand and doesn’t change.

### **Introduction to Vectors**


Vectors in Rust are dynamic arrays, meaning their size can be changed at
runtime (e.g., elements can be added or removed). They are implemented as
smart pointers and manage the memory they point to, automatically handling
deallocation when the vector goes out of scope.

36
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

#### **Creating, Initializing, and Modifying Vectors**

**Example: Basic Vector Operations**

use std::vec; // Not necessary for vec, shown for completeness

fn main()
{
// Creating a New Empty Vector
let mut my_vec: Vec<i32> = Vec::new();

// Pushing Elements onto the Vector


my_vec.push(5);
my_vec.push(10);
println!("Initial Vector: {:?}", my_vec); // [5, 10]

// Initializing with Values Directly


let another_vec = vec![1, 2, 3];
println!("Another Vector: {:?}", another_vec); // [1, 2, 3]

// Accessing Elements (Read)


match another_vec.get(1)
{
Some(element) => println!("The second element is: {}", element),
None => println!("There is no second element."),
}

// Modifying an Element
if let Some(last_element) = my_vec.last_mut()
{
*last_element = 20;
}
println!("Vector after modification: {:?}", my_vec); // [5, 20]
}

37
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

#### **Advantages of Using Vectors**

- **Dynamic Size:**
Vectors can grow or shrink dynamically as elements are added or removed.

- **Memory Management:**
Rust handles the memory for vectors, reducing the risk of memory-related
bugs.

- **Flexibility:**
Useful in scenarios where the amount of data is unknown until runtime.

### **Conclusion**
This lecture has provided a comprehensive overview of working with two
dimensional arrays in Rust, including declaration, accessing, and modifying
elements. Additionally, it introduced vectors as a powerful tool for dynamic
collection management, highlighting their creation, initialization,
modification, and inherent advantages over fixed-size arrays. Understanding
these concepts is crucial for effectively handling data in Rust programming.

### **Exercise Suggestions**

1. **2D Array Operations:**


- Write a program to find the sum of diagonals in a square 2D array.
- Implement a function to transpose a given 2D matrix.

2. **Vector Manipulations:**
- Create a vector, add elements dynamically based on user input, and then
print the updated vector.
- Write a function that takes a vector as an argument, sorts it in ascending
order, and returns the sorted vector.

38
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

fn main()
{
let matrix: [[i32; 3]; 3] =
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];

println!("Element at (1,1): {}", matrix[1][1]);


}

* **Example Code (Vector Intro)**:

fn main()
{
let mut vec = vec![1, 2, 3];
vec.push(4);
println!("{:?}", vec); // Prints: [1, 2, 3, 4]
}

* **Exercises**:
1. Perform operations on a 2D array (e.g., transpose).
2. Explore vector methods (`pop`, `insert`, etc.).

39
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

### Lecture 10: Functions and Parameters in Rust

* **Programming Basics: Reusability with Functions**


#### **Why Functions?**
Before diving into how Rust implements functions, let's cover why functions
are a fundamental concept in programming:

1. **Reusability**:
Write once, use many times. Functions allow you to encapsulate code that
performs a specific task, reducing duplication.

2. **Modularity**:
Break down large programs into manageable pieces, making your code more
organized and easier to maintain.

3. **Abstraction**:
Hide complex implementation details from the caller, providing a simple
interface to interact with your code.

4. **Readability & Maintainability**:


Functions with descriptive names improve code readability, while changes
within a function affect only that module.

#### **Basic Function Structure**


Most programming languages, including Rust, follow a basic structure for
functions:
* **Function Name**:
A unique identifier for the function.
* **Parameters** (Arguments):
Inputs provided to the function (if any).
* **Body**:
The set of statements that define what the function does.
* **Return Type**
The output type of the function, if it returns a value.

40
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

### **Functions in Rust**

#### **Declaring and Calling Functions**

**Example: A Simple "Hello" Function**

// Declaring a function
fn say_hello()
{
println!("Hello, World!");
}

fn main()
{
// Calling the function
say_hello();
}

* `fn` is the keyword to declare a function.


* `say_hello` is the function name.
* The function body prints "Hello, World!" to the console.
* In `main`, we call `say_hello()` to execute its code.

#### **Function Parameters**


**Example: Greeting with a Name**

fn greet(name: &str) {
println!("Hello, {}!", name);
}

fn main() {
greet("Alice");
}

41
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* `name: &str` declares a parameter named `name` of type `&str` (a string


slice).
* When calling `greet("Alice")`, `"Alice"` is passed as an argument to the
`name`
parameter.

#### **Return Types**

**Example: Adding Two Numbers**

fn add(x: i32, y: i32) -> i32


{
x + y
}

fn main()
{
let result = add(5, 3);
println!("Result: {}", result); // Outputs: Result: 8
}
* `-> i32` specifies the return type of the function as `i32`.
* The last expression in the function body is implicitly returned (in this case,
`x + y`).
* In `main`, we assign the returned value to `result`.

#### **The Unit Type `()`**


* If a function doesn't explicitly return a value, it defaults to returning the
unit type `()`. * `()` represents an empty tuple or void, indicating no
meaningful return value.

42
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

**Example: A Function with No Return Value**

fn just_print() -> () // Explicitly showing the default return type


{
println!("Just printing...");
}

fn main()
{
just_print();
}

### **Overview & Learning Objectives Recap**

* **Overview**:
This lecture covered defining reusable functions in Rust with parameters,
understanding how to declare and call them, work with various parameter types,
and handle return types including the unit type `()`.

* **Learning Objectives**:
1. **Define functions with various parameter types**:
* Demonstrated with `&str` (string slice) and `i32` (integer)
examples.
2. **Understand return types and the unit type `()`**:
* Shown through explicit `-> i32` return type declaration and
implicit/default `()` type.

### **Practice Exercises**

1. **Greeter with Age**:


Modify the `greet` function to also accept an age parameter and include it
in the greeting.

2. **Calculator Functions**:
Implement separate functions for basic arithmetic operations (addition,
subtraction, multiplication, division) that take two numbers as parameters

43
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

and return the result.

3. **Guessing Game Logic**:


Create a function that takes a guess and a secret number as parameters,
returning a hint (e.g., "Too high", "Too low", "Correct!") based on the
comparison.

### Lecture 11: Working with Strings in Rust

### Overview
Understanding and manipulating strings is a fundamental aspect of
programming in any language, including Rust. This lecture delves into the
world of strings in Rust, covering the declaration, manipulation, and basic
operations that can be performed on string types, specifically `String` and
`&str`.

### Learning Objectives


* Declare and manipulate string types (`String`, `&str`)
* Perform basic string operations (concatenation, substring extraction,
etc.)
* Explore examples illustrating key concepts

## 1. Declaring String Types in Rust


Rust provides two primary ways to work with strings: the `String` type and
the `&str` type.

### a. `&str` - The String Slice

* **Definition**:
A string slice (`&str`) is a reference to a contiguous sequence of
characters (a string) that is stored elsewhere in memory.

* **Declaration**:
```rust
let hello: &str = "Hello, World!";

44
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

```
* **Key Points**:
+ Immutable by default.
+ The string data is typically stored in the binary itself when directly
assigned as shown above.
+ Can be used for substrings or referencing parts of a `String`.

### b. `String` - The Growable String Type

* **Definition**: A `String` is a growable, owned, and mutable sequence of


characters (a string).

* **Declaration**:

```rust
let mut hello: String = String::from("Hello, ");
```
* **Key Points**:
+ Mutable by declaration with `mut`.
+ Requires the `std::string` module, though usually in scope by default.
+ Can grow or shrink in size at runtime.

## 2. Basic String Operations

### a. Concatenation

* **Using `+` Operator**: Requires one operand to be `&str` and the other to be
`String`. The result is a new `String`.

let hello: &str = "Hello, ";


let world: String = String::from("World!");
let hello_world = hello.to_string() + &world; // Note the use of to_string()
println!("{}", hello_world); // Outputs: Hello, World!

* **Using `format!` Macro**: More flexible for combining multiple strings or


values.

45
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

```rust
let hello = "Hello, ";
let world = "World!";
let hello_world = format!("{}{}", hello, world);
println!("{}", hello_world); // Outputs: Hello, World!
```

### b. Substring Extraction

* **Using Slicing (`&str`)**:

let s: &str = "Hello, World!";


let hello: &str = &s[0..5]; // Note: Rust uses 0-based indexing
println!("{}", hello); // Outputs: Hello

* **Note on Indices**:
Be cautious with direct indexing (`&s[n]`) as it can panic if out
of bounds. Slicing (`&s[m..n]`) also risks panicking if the range is out of
bounds.

### c. Other Operations

* **Length**:

let s: &str = "Hello";


println!("Length of '{}' is {}.", s, s.len()); // Outputs: Length of 'Hello'
is 5.

* **Contains**:

let s: &str = "Hello, World!";


if s.contains("World")
{
println!(" '{}' contains 'World'.", s);
}

46
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

## Examples

### Example 1: Simple String Manipulation

fn main()
{
// Declare a mutable string
let mut greeting: String = String::from("Hello, ");

// Append to the string using push_str


greeting.push_str("Rust!");

// Print the result


println!("{}", greeting); // Outputs: Hello, Rust!
}

### Example 2: Working with `&str` and `String`

fn main()
{
let s: &str = "Initial Content";
let mut owned: String = s.to_string();

// Now 'owned' can be modified


owned.push_str(" - Appended Text");

println!("Owned String: {}", owned);


println!("Original Slice: {}", s);
}

47
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

### Conclusion

Working with strings in Rust involves understanding the nuances between


`String` and`&str`, leveraging each for their respective strengths. By
mastering basic operations such as concatenation, substring extraction, &
more, you can effectively manipulate text data in your Rust applications.

### Homework/Exercises

1. **String Reversal**:
Write a function to reverse a given string.

2. **Case Conversion**:
Implement functions to convert a string to all uppercase and all lowercase.

3. **String Searching**:
Create a program that searches for a substring within a larger text,
highlighting the first occurrence.

fn main()
{
let mut s = String::from("Hello, ");
s.push_str("Rust!");
println!("{}", s); // "Hello, Rust!"

let len = s.len();


println!("Length: {}", len);
}
* **Exercises**:
1. Implement a simple string search function.
2. Explore string formatting with `format!`.

{
greet("Alice");
let result = add(1, 2);
println!("Sum: {}", result);
}

48
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* **Exercises**:
1. Create a function to calculate the area of a rectangle.
2. Implement a function with optional parameters (using `Option`).

49
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

Give me a full complete in detial lecture about the following:


### Lecture 12: Reading and Writing Text Files

* **Overview**: Interacting with text files for data persistence.

* **Learning Objectives**:

+ Read from text files using `std::fs::File` and `BufReader`.


+ Write to text files.

* **Example Code (Reading)**:

use std::fs::File;
use std::io::{self, BufRead};

fn main() -> io::Result<()>


{
let file = File::open("example.txt")?;
for line in io::BufReader::new(file).lines()
{
if let Ok(line) = line
{
println!("{}", line);
}
}
Ok(())
}

50
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* **Example Code (Writing)**:

use std::fs::File;
use std::io;

fn main() -> io::Result<()>


{
let mut file = File::create("example.txt")?;
file.write_all(b"Hello, world!")?;
Ok(())
}

* **Exercises**:

1. Copy the contents of one file to another.


2. Append to an existing file instead of overwriting.

### Lecture 13: Reading and Writing Binary Files

* **Overview**: Working with binary files for more complex data storage.

* **Learning Objectives**:

+ Understand the difference between text and binary files in Rust.


+ Read and write custom data structures to binary files.

51
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

* **Example Code (Writing a Custom Struct)**:

use std::fs::File;
use std::io::{self, Write};

#[derive(Debug)]
struct Person
{
name: String,
age: u8,
}

fn main() -> io::Result<()>


{
let person = Person
{
name: "John".to_string(),
age: 30,
};

let mut file = File::create("person.bin")?;


file.write_all(&bincode::serialize(&person).unwrap())?;
Ok(())
}

* **Note**: This example uses the `bincode` crate for serialization. Ensure to
add it as a dependency in
your `Cargo.toml`.

* **Exercises**:

1. Read back the binary file and print its contents.


2. Experiment with different data structures for binary storage.

52
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

### Lecture 14: Advanced Error Handling and Logging

* **Overview**:
Mastering robust error handling and insightful logging for reliable
applications.

* **Learning Objectives**:
+ Deep dive into `Result` and `Option` for error propagation.
+ Custom error types with `thiserror`.
+ Logging strategies using the `log` crate and its ecosystem (e.g.,
`env_logger`, `tracing`).

* **Example Code**:

use thiserror::Error;

#[derive(Error, Debug)]
enum MyError {
#[error("Failed to read file: {0}")]
Io(#[from] std::io::Error),
#[error("Invalid data")]
InvalidData,
}

fn main() -> Result<(), MyError> {


// Example usage
let _ = std::fs::read_to_string("nonexistent.txt").map_err(MyError::Io)?;
Ok(())
}

* **Exercises**:
1. Implement comprehensive error handling for a command-line tool.
2. Set up logging for a web server using `actix-web` and `tracing`.

53
.Rust Programming Language / Department of Computer Science / By: Saif Basheer Mohammed AlKhoja.
=======================================================================================================

54

You might also like