Hola Mundo!
Welcome to a new article into my Swift 101 series 📝. In this new chapter I'll be sharing a little bit about Control Flow.
Today, we'll learn how to work with the data that we have stored in collections to use it and to make our code make decisions and repeat actions - just like we do in real life!
Think of it this way: when you're following a recipe 👩🏽🍳, sometimes you repeat actions (like stirring), make decisions (like checking if it’s cooked enough?), or choose between different options (What if I don’t have an ingredient?). Control flow in programming helps us do just that: make decisions, repeat actions, and choose paths for our code to follow.
So, let's get to it 💪!
What is Control Flow?
Control flow is the order in which our code's instructions will be executed. It's like being the conductor of an orchestra 🎭, telling each part when to play and under what conditions.
It's our code structure and it will make decisions according to the conditions that are presented.
In Swift, we have several ways to control our code's flow:
- Loops for repeating tasks 🔁
- Conditionals for making decisions ⚖️
- Switch statement for handling multiple options 🔀
Loops: When You Need to Repeat Yourself 🔁
Loops are Swift's way of doing something multiple times. It's like when you're doing exercises - "repeat this 10 times!" 🏋️♀️
They are particularly powerful when working with collections. Remember those Arrays, Sets, and Dictionaries we learned about? Loops help us process each element in these collections efficiently, making it easy to perform operations on multiple pieces of data.
There are many ways to do a loop in Swift: for-in, while, and repeat
- for-in loops:
In a for-in
loop, we iterate over a collection (like an array or set) and access each item one by one.
The syntax in for-in
loops is pretty simple: for itemName in collectionName { what will happen }
let ingredients = ["flour", "sugar", "eggs", "milk"]
for ingredient in ingredients {
print("Found \(ingredient) ✓")
}
// Output:
// Found flour ✓
// Found sugar ✓
// Found eggs ✓
// Found milk ✓
- while loops:
The while loops allow us to check a condition, so Swift will keep looping on our collection while the condition is true, and will stop once the condition fails.
var temperature = 100
while temperature > 75 {
print("Still too hot! Cooling down...")
temperature -= 10
}
print("Ready to serve! 🍽️")
// Output:
// Still too hot! Cooling down...
// Still too hot! Cooling down...
// Still too hot! Cooling down...
// Ready to serve! 🍽️
In the example, the code inside the loop will execute while the temperature is greater than 75, when the 75 is reached then it will stop looping.
- repeat loops:
Not that common, repeat
loops work similar to while
loops but the condition is checked at the end.
var tastings = 1
repeat {
print("Tasting the sauce...")
print("Adding seasoning")
tastings += 1
} while tastings < 3
// Output:
// Tasting the sauce...
// Adding seasoning
// Tasting the sauce...
// Adding seasoning
- Break and continue:
We may want to exit a loop during the iteration, maybe because one of many conditions are achieved. To do so we only need to write the word break
. This will stop the loop.
On the other hand, we may want our loop to skip a specific condition, number, or value and continue iterating over the rest of the collection. And for this we may use the word continue
.
// Use of continue. Checking spoiled ingredients
let ingredients = ["flour", "expired_milk", "eggs", "sugar"]
for ingredient in ingredients {
if ingredient.contains("expired") {
print(" \(ingredient) is spoiled. Skipping...")
continue
}
print("Adding \(ingredient) to mixture")
}
// Output:
// Adding flour to mixture
// Milk is spoiled. Skipping...
// Adding eggs to mixture
// Adding sugar to mixture
// Use of break. Finding the first available cook
let cooks = ["busy", "busy", "available", "busy"]
for status in cooks {
if status == "available" {
print("Found available cook!")
break
}
}
// Output:
// Found available cook
Conditional Statements
As the name implies conditional statements help us to execute the code if those conditions are met or not. In Swift there are two type of conditionals: if
statement and switch
.
👍 By using conditionals, we can make our code more intelligent and responsive!
- if statement
if
statement help us check if a condition is true, if this happens the code will get executed if not it will jump to the next condition that is true.
Imagine you want to go out hiking, you may say, "if tomorrow is sunny, I will go to the mountain". Exactly like that will work on your code, if the condition is meet, then whatever you write down, will happen!
🔎 When declaring if
statement there are a couple of rules you may need to follow
-
if
statement must be followed by a condition which value must return a boolean. - The condition must be followed by a piece of code to be executed between braces {}
- This code will only be executed if the returned value is true.
-
else
statement are optional and can be used to indicate a piece of code that will be executed when theif
condition is false. - In the event that we could have many paths we can use
else if
to check another possible condition.
Simplified will be
if condition {
do this
} else {
do that
}
let ovenTemperature = 180
if ovenTemperature > 200 {
print("Temperature too high! Lower it")
} else if ovenTemperature < 150 {
print("Temperature too low! Increase it")
} else {
print("Temperature is perfect!")
}
// Output:
// Temperature is perfect!
In the example we have a piece of code that checks on the oven temperature. if
the temperature is over 200, will print that is too high, if is down 150 will say is too cold, if none of those conditions are meet that means that the temperature is perfect.
The else
statement is optional, so you may only want something to happen and if the condition is not meet you don't want the code to do anything.
let bakingTime = 30
if bakingTime == 30 {
print("Open the oven")
}
// Output:
// Open the oven
- Multiple conditions for an if
There's the possibility that we may need to check multiple conditions for something to happen. In this case we could use logical operators like && (AND) and || (OR) to combine conditions in our if
condition.
let hasIngredients = true
let hasRecipe = true
if hasIngredients && hasRecipe {
print("Let's start cooking!")
} else {
print("We need to prepare better")
}
// Output:
// Let's start cooking!
In the example we want to check if both conditions are meet. So if
we have both ingredients and recipe, we can start cooking. Otherwise we can't.
- Ternary operators
Ternary operators are if
statements but with a one line syntax. The syntax is A ? B : C
✨ Where ✨
- A is the condition we want to check
- B is the code to execute if A is true (the if)
- C is the code to execute if A is false (the else)
let kitchenIsClean = true
kitchenIsClean ? print("Ready to cook!") : print("Clean kitchen first!")
// Output:
// Ready to cook!
Switch
switch
statements allow us to compare the value of a condition with many cases until it finds one that matches.
To use a switch
statement there are some things to take into consideration:
- The conditional must be initiated with the
switch
word - Each case we want to evaluate goes with a name and two points to be executed
case caseName:
- When the condition matches a case the code will be executed and the
switch
will end. This means that no other conditions will be checked - Similar to an
else
statement, thedefault
code will be executed if no case matches.
let mealType = "dessert"
switch mealType {
case "breakfast":
print("Serving from 7-11 AM")
case "lunch":
print("Serving from 12-3 PM")
case "dinner":
print("Serving from 6-10 PM")
case "dessert":
print("Available all day!")
default:
print("Kitchen closed")
}
// Output:
// Available all day!
In the example, Swift will check each case until it finds the one that matches the condition and will execute the code, in this case, a print.
- Switch with Interval Matching
One of the switch
characteristics is that it allows us to check inside intervals for a match.
let temperature = 175
switch temperature {
case 1...100:
print("Too cold!")
case 101...160:
print("Getting there...")
case 161...180:
print("Perfect temperature!")
case 181...300:
print("Too hot!")
default:
print("Check thermometer!")
}
// Output:
// Perfect temperature!
This demonstrates how you can use switch statements in Swift to match ranges of values, which is a very powerful way to handle different conditions that fall within specific intervals.
- Compound cases
Just as the interval matching allows us to check a range, compound cases allow us to add many values to a same case.
let cookingMethod = "baking"
switch cookingMethod {
case "baking", "roasting":
print("Use the oven")
case "frying", "sautéing":
print("Use the stove")
case "steaming", "boiling":
print("Use a pot with water")
default:
print("Check recipe for method")
}
// Output:
// Use the oven
- Switch with Enums
Remember the Enums we learned in the previous article? switch
statements work great with them! In fact, when using switch with enums, Swift requires us to handle all possible cases or include a default case this gives an extra layer of security, knowing that you are handling all cases in your enum.
This combination of enum and switch is one of the most powerful features in Swift. Since enums have a finite set of cases, and switch
must be exhaustive, Swift can guarantee at compile time that we're handling all possible scenarios - making our code safer and more maintainable.
enum CookingStatus {
case preparing
case cooking
case ready
case burned
}
let status = CookingStatus.cooking
switch status {
case .preparing:
print("Getting ingredients ready")
case .cooking:
print("Keep an eye on the temperature!")
case .ready:
print("Time to serve!")
case .burned:
print("Order takeout...")
}
// Output:
// Keep an eye on the temperature!
When using switch with enums🕵🏽♀️:
- You don't need to specify the enum type in each case (writing .cooking)
- Swift will verify that you covered all possible cases
- If you don't want to handle all cases, you must include a default
- The compiler will give you an error if you miss a case and don't have a default
__
By using control flow statements, we can enhance the logic and functionality of our code. They provide a clear way to handle different scenarios and repetitive tasks, making your code more organized and expressive.
I hope this overview helps you appreciate the power of control flow in Swift and inspires you to continue learning this amazing language! 🤍
Want to keep learning about Swift?
This a full series on Swift 101, the next chapter will be Functions and closures, so I hope to see you there!
Remember that you can always go further into this information by checking the official documentation and courses here
If you enjoyed this, please share, like, and comment. I hope this can be useful to someone and that it will inspire more people to learn and code with Swift
Top comments (0)