Shubham Mishra
Shubham Mishra

Reputation: 1331

Return statement in IF LET vs GUARD LET

Look at the following two scenarios with same code:

Using IF LET:

public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?){
    if let error = error {
        print("error: \(error.localizedDescription)")
        return
    }
        for service in peripheral.services!
        {
            print("discovered service is ::::",service)
        }
}

Using GUARD LET:

public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?){
        guard let _ = error else{
            for service in peripheral.services!
            {
                print("discovered service is ::::",service)
            }
        return
       }
    }

Both of them are using return statement and both of them serve the same purpose then what are the differences and which one is better?

EDITS:-

Problem is for general statement it's fine to use any of them but when we have error to handle which one is best to use ?

Upvotes: 2

Views: 2713

Answers (3)

Zaid Pathan
Zaid Pathan

Reputation: 16820

First of all, None of them is properly implemented.

  • In peripheral.services! if services will be nil, it will crash.
  • Return statement - There is no necessity of return in both, you can just remove it from if-let and everything will work fine
  • The benefit of guard over if-let is it reduces if-else brackets resulting more readable code
  • You use guard if you care about value of variable outside the block scope, think about if-let you can only use unwrapped variable inside block only.
  • Use if-let for small number of variables unwrapping and value of unwrapped variable not required outside block scope
  • Use guard-else for using unwrapped variables outside block scope
  • If you are going to use error object outside the block scope(main use of guard block) then go with guard-else otherwise go with if-let.

Upvotes: 3

Tom E
Tom E

Reputation: 1607

The usage of guard in this scenario makes your intention clearer—you only want the function to execute if there is no error.

What I like best about guard is that it keeps you from deeply nesting if brackets which makes the code more readable. In your code, to make this happen, you would, however, put it in a format like this:

guard error != nil else { return }
... // continue with regular code

Apart from that guard and if yield the same result—it mostly is a matter of taste.

Upvotes: 3

Michał Kwiecień
Michał Kwiecień

Reputation: 2874

Guard statements are very good for dealing with "pyramids of doom". The way I'm using it is for example keyboard notification:

func keyboardWillShowSelector(notification:NSNotification) {
        guard let userInfo = notification.userInfo else { return }
        var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        keyboardFrame = self.view.convert(keyboardFrame, from: nil)
        let height = keyboardFrame.size.height
        keyboardWillShow(withHeight: height)
}

Without guard statement it will have another intent and the code will not be so clean:

func keyboardWillShowSelector(notification:NSNotification) {
        if let userInfo = notification.userInfo {
            var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
            keyboardFrame = self.view.convert(keyboardFrame, from: nil)
            let height = keyboardFrame.size.height
            keyboardWillShow(withHeight: height)
        }
}

Another great example is validation:

private func errorFromInputValidation(name: String, email: String, password1: String, password2: String) -> String? {
        guard password1 != "" && password2 != "" && email != "" && name != ""  else { return Localizable.fieldsCannotBeEmpty.localized }
        guard password1 == password2 else { return Localizable.passwordsAreNotEqual.localized }
        return nil
}

Upvotes: 2

Related Questions