if let
and guard let
are two conditional operators or condition checker which make our life super easy. Other languages have only if
as condition checker but swift provides if let
as well as guard let
also which are operationally same but a bit different in functionality.
To understand their differences, let’s try to understand what they are in details first.
if condition
Normal if
condition is nothing but to check whether a condition is true or not.
let colors = ["red", "green", "blue"]
if colors.contains("red") {
print("red is present in palette")
}
This can be clubbed with else
and else if
but both of them are optional.
let colors = ["red", "green", "blue"]
if colors.contains("red") {
print("red is present in palette")
} else {
print("red is not present in palette")
}
we can even club multiple if
conditions with simple &&
or ||
operators based on the use case.
let colors = ["red", "green", "blue"]
if colors.contains("red") || colors.contains("green") {
print("red or green are present in palette")
} else {
print("red and green both are not present in palette")
}
if let
Now let’s think about someplace where we want to compute something and based on the computed value we need to put an if
condition.
let colors = ["red", "green", "blue"]
let index = colors.firstIndex(where: {$0.elementsEqual("green")})
if index != nil {
print("green is present in palette at position \(index ?? -1)")
} else {
print("green is not present in palette")
}
We are trying to check if an element is present in an array and if present we are trying to print its position.
The same code can be replaced with if let
instead of if
condition.
let colors = ["red", "green", "blue"]
if let index = colors.firstIndex(where: {$0.elementsEqual("green")}) {
print("green is present in palette at position \(index)")
} else {
print("green is not present in palette")
}
We combined the computation and evaluation within a single statement by using if let
.
The thing to notice here is that the variable index
is not nullable in if let
whereas it was a nullable variable in if
condition.
We can club multiple if let
also within the same condition check by spearating them using comma ,
let colors : [String] = ["red", "green", "blue"]
if let redIndex = colors.firstIndex(where: {$0.elementsEqual("red")}),
let greenIndex = colors.firstIndex(where: {$0.elementsEqual("green")}) {
print("red is present in palette at position \(redIndex) and green is present in palette at position \(greenIndex)")
} else {
print("\(red) and \(green) are not present in palette")
}
Or we can even check the nullability and assign it to another variable that will be non-nullable. This is called optional unwrapping.
let colors : [String]? = ["red", "green", "blue"]
let nullableGreen : String? = "green"
if let green = nullableGreen,
let index = colors?.firstIndex(where: {$0.elementsEqual(green)}) {
print("\(green) is present in palette at position \(index)")
} else {
print("\(nullableGreen ?? "undefined") is not present in palette")
}
The thing to notice here is that the variable green
is only accessible only in if let
but not in the else
scope. It’s not event available after the if else scope.
let colors : [String]? = ["red", "green", "blue"]
let nullableGreen : String? = "green"
if let green = nullableGreen,
let index = colors?.firstIndex(where: {$0.elementsEqual(green)}) {
print("\(green) is present in palette at position \(index)")
} else {
print("\(nullableGreen ?? "undefined") is not present in palette")
}
print(green) <e>//Compile type error: cannot find 'green' in scope</e>
guard let
guard let
can also be used for condition check and it can also unwrap the optional values but it works a bit different from if let
.
guard let
is designed to exit the current function, loop, or condition if the check fails.
func checkColorInPalette() {
let colors : [String] = ["red", "green", "blue"]
guard let index = colors.firstIndex(where: {$0.elementsEqual("green")}) else {
print("green is not present in palette")
return
}
print(print("green is present in palette at position \(index)"))
}
Similar to if let
, guard let
can also be clubbed with multiple let conditions using comma ,
and it can also be used for optional unwrapping.
func checkColorInPalette() {
let colors : [String] = ["red", "green", "blue"]
let nullableGreen : String? = "green"
guard let green = nullableGreen,
let index = colors.firstIndex(where: {$0.elementsEqual(green)}) else {
print("green is not present in palette")
return
}
print(print("\(green) is present in palette at position \(index)"))
}
The important thing to notice here is that the let
variables defined in guard statements are also accessible after the statement but they are inaccessible inside the else condition.
Difference between if and if let/guard let
if
is just a conditional checker whereasif let
andguard let
can define variables also where we can do computation.- We can club multiple conditions or expression in all three.
- Only
if let
orguard let
can do the optional unwrapping.
Difference between if let and guard let
if let
is similar toif
condition with the additional functionality of defininglet
variable where we can do the computation or optional unwrapping.guard let
is also similar toif let
but it focus on the “happy path” means if the condition is nottrue
, code will not execute further in that particular function, loop or condition but it will return, break or throw.- In
if let
, the definedlet
variables are available within the scope of that if condition but not inelse
condition or even below that.
In guard let
, the defined let
variables are not available in the else
condition but after that, it’s available throughout till the function ends or anything.