GO FURTHER, FASTER: Try the Swift Career Accelerator today! >>

guard let in swiftui

Forums > 100 Days of SwiftUI

hey everyone, I'm trying to go through the lessons in day 14 again so that I can solve checkpoint 9. I apologize in advance if I am not learning as fast but I can promise that I am really trying.

Here's one thing that I wasn't able to notice before but I only noticed right now while rewatching the "How to unwrap optionals with guard" lecture.

in guard let, why is it that we immediately go to the else block? why can't guard let have an if block? This is confusing me because I thought if else statements should always follow the following format

if statement {
}
else if statement (can be as many else if statements as you want) {
}
else statement (can only be one else staement) {
}

However, guard let doesn't follow this format. Why? And I can't see the purpose of guard let when if let also covers the same thing. This is making me have a hard time grasping the concept and use case of guard let.

I understand that guard let only runs if our optional DOES NOT have a value inside. Can't if let also cover it since it'll also run the block after the if statement if our optional also doesn't have a value? It'll only run the if let statement if there's a value inside making it better than guard let. Doesn't that make the concept of guard let kind of redundant?

3      

You shall not pass!

When I first read about Swift's guard statement, I thought it was brilliant. I imagined Beefeater guards standing outside the Towers of London in their impratical scarlet and gold uniforms with their pikes challenging anyone trying to get in.

If you knew the password, or had the right credentials, the Beefeaters let you pass. You were free to enter and go where you pleased. If not, you weren't even allowed inside. End of story.

In a guard letstatement, the guard on duty is checking to see if your variable actually contains a value or not. The guard challenges the variable ticket. Before being allowed to pass the guard, the variable must prove that it actually has a value and isn't nil. If the variable is nil, access denied. There's the exit. Scram.

let vipEntryPass = String?  // setup a ticket system

// Call the function
attempEntryIntoTowers(using: vipEntryPass ) // may have a value? may be nil ?

func attemptEntryIntoTowers(using ticket: String?) {
    // Here the Beefeater asks for a ticket.
    guard let entryPass = ticket  else { return } // No ticket? NO ENTRY FOR YOU! 

    let someIcon      = selectIcon( using: ticket!   ) // DANGER! variable ticket may be nil. DO NOT DO THIS.
    let someOtherIcon = selectIcon( using: entryPass ) // OK! entryPass is guaranteed to be a String.
    // If the guard allows you to pass, then your variable entryPass is valid for the rest of this function.
    // AND you don't need to check it to see if it's nil.  From here to the end, it's a String!

    //  .....[snip].... hundreds of more lines of Swift code evaluating the entryPass variable.
}  // When the function ends, entryPass is out of scope and no longer valid.

If the guard sees you're trying to get in without a ticket, he denies your visa. No entry for you!

3      

Early exit from a function improves readability and is probably the main attraction of guard.

But guard let also has a useful feature that if let doesn't: Any variables unwrapped in the guard let are available in the rest of the function. With an if let, unwrapped variables are only available within the brackets of the if statement and not in the rest of the function.

A lot of times, you can use either a guard or an if, they just have to be structured differently.

func scrapePage1(_ urlString: String) -> String {
    guard let url = URL(string: urlString) else {
        return "invalid url"
    }

    var contents: String = ""
    //scrape webpage into contents

    return contents
}

func scrapePage2(_ urlString: String) -> String {
    if let url = URL(string: urlString) {
        var contents: String = ""
        //scrape webpage into contents
        return contents
    } else {
        return "invalid url"
    }
}

You can see that in scrapePage2, you have to scan all the way down to the bottom of the if statement to see what happens if you don't have a valid url. But in scrapePage1, you get that out of the way up front and then the rest of the function reads normally.

3      

I'm a bit confused here

In a guard letstatement, the guard on duty is checking to see if your variable actually contains a value or not. The guard challenges the variable ticket. Before being allowed to pass the guard, the variable must prove that it actually has a value and isn't nil. If the variable is nil, access denied. There's the exit. Scram.

I thought guard let will only run if Swift unwraps our value and finds out that the unwrapped value DOES NOT contain a value. If the unwrapped variable has a value, it won't run the guard let statement. Is my understanding wrong?

In this line in the code,

guard let entryPass = ticket else { return }

Doesn't that mean it goes inside the else block and returns nothing or (goes out the function since it's a return statement)

I also have another question. This is my first time encountering a not (!) operator after a variable

let someIcon = selectIcon( using: ticket! )

doesn't ! signify not and is supposed to be for booleans?

Lastly, is my understanding in this part correct?

let someOtherIcon = selectIcon( using: entryPass )

Since we unwrapped entryPass using guard let, and assigned a parameter ticket into it, that means we can use the passed parameter (entryPass) inside the whole attemptEntryIntoTowers() function? (although I'm not quite sure what selectIcon is for).

Also, why did you mention that

// If the guard allows you to pass, then your variable entryPass is valid for the rest of this function. // AND you don't need to check it to see if it's nil. From here to the end, it's a String!

I think I'm still a bit confused with the concept of guard let. I always assumed that it'll only run the else statement if the unwrapped optional is nil/empty.

Apologies for the barrage of questions. I just wanted to make sure that I really understand this but right now, I'm really having a hard time grasping this concept.

I do get the beefeaters example/analogy though!

3      

I see, so contents is available in the whole function after the guard let block while contents is only available inside the if block in the if let right?

3      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure and A/B test your entire paywall UI without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.