WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

SOLVED: day 12 - optionals summary-test 11,q6. guard //without the let

Forums > 100 Days of Swift

struct Dog {
    var name: String
    init?(name: String) {
        guard name == "Lassie" else { //error message when "guard let": Pattern matching in a condition requires the 'case' keyword
            print("Sorry, wrong dog!")
            return nil
        }
        self.name = name
    }
}
let dog = Dog(name: "Fido")

Hi, how come the guard works without the "let" keyword and does not work with "guard let"? i thought its always "guard let" but seems not true for some reason..

1      

guard doesn't always have to be followed by a let, just as if doesn't have to. It's only guard let or if let if you need to unwrap an Optional and bind it to a constant or variable or if you are pattern matching with guard case or if case.

guard simply says "check this condition and fail if it doesn't pass".

guard let is "check that this Optional has a value and fail if it is nil. Oh, and by the way, if it passes you can use the let variable in your current scope. You're welcome."

In the example provided, you are just checking the value of the name variable and failing if it doesn't match what you expect. You would use guard let here if, say, name was a String? (i.e., an optional string) and you were checking if it was nil.

2      

Ok, thanks @roosterboy. guard let is to check if optional value exists or is nil and guard is just to check if condition is true or false.

I modified code to make initialiser with optional parameter to use guard let first and then when its true, jump to guard statement to check condition.

struct DogOptional {
    var name: String?
    init?(nameOptional: String?) {
        guard let unwrapped = nameOptional else { //guard with let because parameter is optional.
            print("Sorry, entry not received!")
            return nil
        }
        guard unwrapped != "Lassie" else{
            print("Sorry, wrong dog name!")
            return nil
        }
        self.name = unwrapped
        print("Dog name is: \(name!)")
    }
}
let dogObj = DogOptional(nameOptional: "Lassie")

1      

And just as an FYI, you can often combine these two into onne guard:

        guard let unwrapped = nameOptional,  unwrapped != "Lassie" else {
            return nil
        }

Not in your specific example, if you want to maintain two separate error messages, but just be aware that it's possible.

2      

Thanks @roosterboy for showing how to shorten the code by putting the 2 conditions into one line :D

1      

Hacking with Swift is sponsored by Emerge

SPONSORED Why are Swift reference types bad for app startup time, and what’s the performance cost of protocol conformances? That’s just a couple of the topics you can learn about on the Emerge blog — written by the app performance experts behind Emerge’s advanced app optimization and monitoring tools, based on their experience of working at companies like Apple, Airbnb, Snap, and Spotify.

Find out more

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.