Reputation: 1331
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
Reputation: 16820
First of all, None of them is properly implemented.
peripheral.services!
if services
will be nil, it will crash.if-let
and everything will work fineguard
over if-let
is it reduces if-else
brackets resulting more readable codeguard
if you care about value of variable outside the block scope, think about if-let
you can only use unwrapped variable inside block only.if-let
for small number of variables unwrapping and value of unwrapped variable not required outside block scopeguard-else
for using unwrapped variables outside block scopeerror
object outside the block scope(main use of guard block) then go with guard-else
otherwise go with if-let
.Upvotes: 3
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
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