Swift: Guard Let vs If Let

I have been reading about Optionals in Swift, and I have seen examples where if let is used to check if an Optional holds a value, and in case it does – do something with the unwrapped value.

However, I have seen that in Swift 2.0 the keyword guard let is used mostly. I wonder whether if let has been removed from Swift 2.0 or if it still possible to be used.

Should I change my programs that contain if let to guard let?

0

9 Answers

if let and guard let serve similar, but distinct purposes.

The "else" case of guard must exit the current scope. Generally that means it must call return or abort the program. guard is used to provide early return without requiring nesting of the rest of the function.

if let nests its scope, and does not require anything special of it. It can return or not.

In general, if the if-let block was going to be the rest of the function, or its else clause would have a return or abort in it, then you should be using guard instead. This often means (at least in my experience), when in doubt, guard is usually the better answer. But there are plenty of situations where if let still is appropriate.

5

Guard can improve clarity

When you use guard you have a much higher expectancy for the guard to succeed and it's somewhat important that if it doesn't succeed, then you just want to exit scope early. Like you guard to see if a file/image exists, if an array isEmpty or not.

func icon() -> UIImage {
    guard let image = UIImage(named: "Photo") else {
        return UIImage(named: "Default")! //This is your fallback
    }
    return image //-----------------you're always expecting/hoping this to happen
}

If you write the above code with if-let it conveys to the reading developer that it's more of a 50-50. But if you use guard you add clarity to your code and it implies I expect this to work 95% of the time...if it ever failed, I don't know why it would; it's very unlikely...but then just use this default image instead or perhaps just assert with a meaningful message describing what went wrong!

  • Avoid guards when they create side effects, guards are to be used as a natural flow. Avoid guards when else clauses introduce side effects. Guards establish required conditions for code to execute properly, offering early exit

  • When you perform significant computation in the positive branch, refactor from if to a guard statement and returns the fallback value in the else clause

From: Erica Sadun's Swift Style book

Also as a result of the above suggestions and clean code, it's more likely you will want/need to add assertions into failed guard statements, it just improves readability and makes it clear to other developers what you were expecting.

guard​ ​let​ image = ​UIImage​(named: selectedImageName) else { // YESSSSSS
     assertionFailure(​"Missing ​​\(​selectedImageName​)​​ asset"​) 
     return
} 

guard​ ​let​ image = ​UIImage​(named: selectedImageName) else { // NOOOOOOO
​     ​return 
}

From: Erica Sadun's Swift Style book + some modifications

(you won't use asserts/preconditions for if-lets. It just doesn't seem right)

Using guards also help you improve clarity by avoiding pyramid of doom. See Nitin's answer.


Elena Rostova

Elena Rostova

Lead Health, Wellness & Medical Journalist

Elena Rostova holds a Master's degree in Public Health Journalism. She covers groundbreaking medical research, holistic wellness trends, mental health awareness, and nutritional science.