Swift: "guard" vs "if", and "guard let" vs "if let"

#Swift: `guard` 対 `if`　と、　`guard let` 対 `if let` ([日本語](https://qiita.com/loic-meister-guild/items/ec55eee62350649c8994))
It would be more appropriate to see this question as `guard` vs `if` and `guard let` vs `if let`.
## `guard` vs `if`
Standalone `guard` and `if` are both simple flow control statements and do not do any unwrapping.

`guard` just exits early if its condition isn't met.
### Comparison table
|| `guard` | `if` |
|:---:|:---:|:---:|
| Function | Early exit | Flow control |
| Focus on ... | ... the "**early exit path**": checking conditions are correct before going further. | ... the “**happy path**”: the behavior of our function when everything has gone according to plan. |
| Readability, Clarity | **Improved** | Can lead to **pyramids of doom** |
| Nested Scope (adds levels of depth) | ❌ | ◯ |
| Enclosing Scope | Necessary | Not necessary |
| Must ... | return from the scope if the check fails | |
| Return / Throw | Necessary | Not necessary |
| Think of it as ... | ... validation. | ... simple flow control |
| Preferred location | At the start of the scope |  |
### Examples
```code:guard
let array = ["a", "b", "c"]
func at(at index: Int) -> String?{
   // exit early when index is out of bound
   guard index >= 0, index < array.count  else { return nil }
   return array[index]
}
print(at(1))
```
```code:if
let array = ["a", "b", "c"]
let index = 1
if index >= 0, index < array.count {
    print(array[index])
} else {
    print(nil)
}
```
## `guard let` vs `if let`
`guard let` and `if let` both unwrap optionals.

`guard let`, like `guard`, exits early if its condition isn't met.
### Comparison table
|| `guard let` | `if let` |
|:---:|:---:|:---:|
| Function | Unwraps optionals | Unwraps optionals |
| Designed to ... | ... exit the current scope if the check fails. | ... just unwrap some optionals. |
| Focus on ... | ... the "**early exit path**": checking conditions are correct before going further. | ... the “**happy path**”: the behavior of our function when everything has gone according to plan. |
| Enclosing Scope | Necessary | Not necessary |
| Must ... | return from the scope if the check fails | |
| Return / Throw | Necessary | Not necessary |
| Readability, Clarity | **Improved** | Can lead to **pyramids of doom** |
| Nested Scope (adds levels of depth)  | ❌ | ◯ |
| Visibility | The unwrapped optional is **visible** in the scope **after** the `guard let` statement.  | The unwrapped optional is **only visible** in the `if let` statement's code block scope |
| Think of it as ... | ... validating then unwrapping some optionals. | ... just unwrapping some optionals. |
| Preferred location | At the start of the scope |  |
| Unwrap multiple optionals at once | ◯ | ◯ |
| Side Effects | Should be avoided | Ok |
### Examples
##### `guard let`
All the strings (firstNameString, lastNameString, emailString, passwordString) are accessible in the scope after the guard statements, if all the fields are valid:

```code:guard-let
func validateThenRegisterUser() {
    // validation
    guard let firstNameString = firstName.text where firstNameString.characters.count > 0 else {
            firstName.becomeFirstResponder()
            return
        }
    guard let lastNameString = lastName.text where lastNameString.characters.count > 0 else {
            lastName.becomeFirstResponder()
            return
        }
    guard let emailString = email.text where 
        emailString.characters.count > 3 &&
        emailString.containsString("@") && 
        emailString.containsString(".") else {
            email.becomeFirstResponder()
            return
        }
    guard let passwordString = password.text where passwordString.characters.count > 7 else {
            password.becomeFirstResponder()
            return
        }

    // The validated information can now be used for registration
    let newUser = User()
    newUser.firstName = firstNameString
    newUser.lastName = lastNameString
    newUser.email = emailString
    newUser.password = passwordString
    APIHandler.sharedInstance.registerUser(newUser)
}
```
##### `if let`
All the strings (firstNameString, lastNameString, emailString, passwordString) are accessible only within the scope of the `if` statement code block.

This creates a "pyramid of doom" which presents many issues like:

- readability,
- ease of reordering/refactoring the code. For example, if the fields' validation order was altered, you would have to rewrite most of the code.

```code:if-let
func validateThenRegisterUser() {
    // validation: starts the pyramid of doom
    if let firstNameString = firstName.text where firstNameString.characters.count > 0{
        if let lastNameString = lastName.text where lastNameString.characters.count > 0{
            if let emailString = email.text where emailString.characters.count > 3 && emailString.containsString("@") && emailString.containsString(".") {
                if let passwordString = password.text where passwordString.characters.count > 7{
                    // The validated information can now be used for registration
                    let newUser = User()
                    newUser.firstName = firstNameString
                    newUser.lastName = lastNameString
                    newUser.email = emailString
                    newUser.password = passwordString
                    APIHandler.sharedInstance.registerUser(newUser)
                } else {
                    password.becomeFirstResponder()
                }
            } else {
                email.becomeFirstResponder()
            }
        } else {
            lastName.becomeFirstResponder()
        }
    } else {
        firstName.becomeFirstResponder()
    }
}
```