diff --git a/src/SUMMARY.md b/src/SUMMARY.md index d64afd8..c2bc5f5 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -40,7 +40,7 @@ Introduction - [Flow Control](chap_04/intro.md) - [Conditionals](chap_04/conditionals.md) - [If statement](chap_04/if_statement.md) - - [If else](chap_04/if_else.md) + - [else if](chap_04/else_if.md) - [If else expression](chap_04/if_else_expression.md) - [Loops](chap_04/loops.md) - [loop](chap_04/loop.md) diff --git a/src/chap_04/conditionals.md b/src/chap_04/conditionals.md index b3a49b7..bb0e8b1 100644 --- a/src/chap_04/conditionals.md +++ b/src/chap_04/conditionals.md @@ -1 +1,5 @@ -# Conditionals +
+ Control Flow in Rust: Conditionals in Rust +
+ +Control flow is an essential part of programming that allows you to make decisions and execute different code paths based on certain conditions. In Rust, the primary control flow structures for making decisions are `if`, `else`, and `else if`. diff --git a/src/chap_04/else_if.md b/src/chap_04/else_if.md new file mode 100644 index 0000000..8280a86 --- /dev/null +++ b/src/chap_04/else_if.md @@ -0,0 +1,105 @@ +
+ The `else if` Statements +
+ +The `else if` statement allows you to specify a new condition to check if the previous if condition is false. This helps in checking multiple conditions sequentially. + +- **Syntax** + +```rust +if condition1 { + // code to execute if condition1 is true +} else if condition2 { + // code to execute if condition2 is true +} else { + // code to execute if none of the above conditions are true +} +``` + +### Example + + +```Rust +fn main() { + let number = 0; + + if number > 0 { + println!("The number is positive."); + } else if number < 0 { + println!("The number is negative."); + } else { + println!("The number is zero."); + } +} +main(); +``` + + The number is zero. + + +- In this example: + - The first condition number > 0 is false. + - The second condition number < 0 is also false. + - Since both conditions are false, the code inside the else block is executed, printing "The number is zero." + +### Using Conditions with `let Bindings` + +- Rust allows you to use if, else, and else if conditions in combination with let bindings for more concise and expressive code. + +```rust +let my_var = if cond {result} else {the_other_result} +``` + +### Example + + +```Rust +fn main() { + let number = 5; + let is_positive = if number > 0 { + true + } else { + false + }; + + println!("Is the number positive? {}", is_positive); +} +main(); +``` + + Is the number positive? true + + +- In this example, the variable is_positive is assigned the value true if number > 0 and false otherwise. This is a concise way to handle simple conditions and bindings. + +### Summary + +- if Statement: Executes a block of code if a specified condition is true. +- else Statement: Specifies a block of code to execute if the if condition is false. +- else if Statement: Allows for checking multiple conditions sequentially. +- Using Conditions with let Bindings: Enables concise and expressive code by combining conditions with variable bindings. + +### Example Combining All Concepts + + +```Rust +fn main() { + let number = 10; + + let description = if number > 0 { + "positive" + } else if number < 0 { + "negative" + } else { + "zero" + }; + + println!("The number is {} and it is {}.", number, description); +} +main(); +``` + + The number is 10 and it is positive. + + +In this comprehensive example, the description variable is assigned a string based on the value of number, and the final message prints out the number and its description. This demonstrates the flexibility and power of Rust's control flow structures. diff --git a/src/chap_04/if_statement.md b/src/chap_04/if_statement.md index d1deb22..7c89244 100644 --- a/src/chap_04/if_statement.md +++ b/src/chap_04/if_statement.md @@ -1 +1,213 @@ -# If statement +
+ The if statement +
+ + +The `if` statement allows you to execute a block of code only if a specified condition is true. + +### Syntax + +```rust +if condition { + // code to execute if condition is true +} +``` + +- The curly braces `{}` are required even if there is only one statement. + +### Example + + +```Rust +fn main() { + let number = 5; + + if number > 0 { + println!("The number is positive."); + } +} +main(); +``` + + The number is positive. + +In this example, the condition number > 0 is true, so the code inside the if block is executed, printing "The number is positive." + +```rust +// Trying to remove the curly braces +fn main() { + let number = 5; + + if number > 0 + println!("The number is positive."); + +} +main(); +``` + +- This will produce an error: + +```text +Error: expected `{`, found `println` + ╭─[command_9:1:1] + │ + 5 │ if number > 0 + │ ─────┬──── + │ ╰────── note: the `if` expression is missing a block after this condition + 6 │ println!("The number is positive."); + │ ───┬─── + │ ╰───── expected `{` +───╯ +``` + + +```Rust +// adding parentheses +fn main() { + let number = 5; + + if (number > 0) { + println!("The number is positive."); + } +} +main(); +``` + + The number is positive. + + +- In jupyter notebook, no warnings are shown, I am not sure the reason why, however, if you run in text editor you will get warnings for using parentheses. + +## Conditions Must Be Boolean + +In Rust, conditions must explicitly evaluate to a boolean value (`true` or `false`). Unlike some other programming languages, you cannot implicitly compare values against `0`, empty strings, or other non-boolean types. + +### Example of Invalid Conditions + +- The following examples will produce errors because the conditions are not explicitly boolean: + +```rust +fn main() { + let number = 5; + + // Error: expected `bool`, found integer + if number { + println!("This will not compile."); + } + + let text = ""; + + // Error: expected `bool`, found `&str` + if text { + println!("This will not compile either."); + } +} +``` + +- Here is the error from the previous code + +```text +[E0308] Error: mismatched types + ╭─[command_7:1:1] + │ + 5 │ if number { + │ ───┬── + │ ╰──── expected `bool`, found integer +───╯ +[E0308] Error: mismatched types + ╭─[command_7:1:1] + │ + 12 │ if text { + │ ──┬─ + │ ╰─── expected `bool`, found `&str` +────╯ +``` + +### Implicit Checking Against `0` + +- If we try to implicity check against `0`, we will get an error. +```rust +fn main() { + let num = 0; + if num { + println!("Something"); + } +} +main(); +``` + +- If you run this code, you will get the following error: + +```text +[E0308] Error: mismatched types + ╭─[command_19:1:1] + │ + 3 │ if num { + │ ─┬─ + │ ╰─── expected `bool`, found integer +───╯ +``` + +### No Parentheses Needed + +- In Rust, conditions do not need to be enclosed in parentheses, although you can use them for clarity if desired. + + +```Rust +fn main() { + let number = 5; + + // Both styles are valid + if number > 0 { + println!("No parentheses needed."); + } + + if (number > 0) { + println!("Parentheses are optional."); + } +} +main(); +``` + + No parentheses needed. + Parentheses are optional. + + +### The `else` Statements + +- The else statement allows you to specify a block of code to execute if the if condition is false. + +- **Syntax** +```rust +if condition { + // code to execute if condition is true +} else { + // code to execute if condition is false +} +``` + +### Example + + +```Rust +fn main() { + let number = -5; + + if number > 0 { + println!("The number is positive."); + } else { + println!("The number is not positive."); + } +} +main(); +``` + + The number is not positive. + + +- In this example, the condition number > 0 is false, so the code inside the else block is executed, printing "The number is not positive." + + + + + diff --git a/src/chap_04/intro.md b/src/chap_04/intro.md index cf0c99f..03f84db 100644 --- a/src/chap_04/intro.md +++ b/src/chap_04/intro.md @@ -1 +1,25 @@ -# Flow Control +## Chapter Introduction: Control Flow in Rust + +Control flow is a fundamental concept in programming, dictating the order in which statements and instructions are executed. Understanding control flow is essential for writing efficient and effective code. In Rust, control flow constructs allow you to manage the execution path of your programs based on conditions, loops, and pattern matching. + +### What We Will Cover in This Chapter + +In this chapter, we will delve into the various control flow mechanisms provided by Rust. We will explore: + +1. **Conditional Statements**: + - **`if` and `else`**: Learn how to make decisions in your code based on boolean conditions. + - **`else if`**: Handle multiple conditions and branching logic. + +2. **Loops**: + - **`loop`**: Create infinite loops and learn how to break out of them. + - **`while`**: Execute a block of code repeatedly while a condition holds true. + - **`for`**: Iterate over collections and ranges in a concise and readable manner. + +3. **Pattern Matching**: + - **`match`**: A powerful control flow construct that allows you to branch code based on the value of a variable, enabling more readable and maintainable code. + - **`if let`** and **`while let`**: Simplify complex conditional and looping constructs with pattern matching. + +4. **Error Handling**: + - **`Result` and `Option`**: Handle potential errors and optional values gracefully using Rust's type system and pattern matching. + +By the end of this chapter, you will have a solid understanding of Rust's control flow constructs and how to use them to write clear, concise, and efficient code. These tools will enable you to manage the execution of your programs effectively, handle different scenarios, and build robust applications.