Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Vending Machine App in Swift 2.0 Using the Vending Machine Displaying Icons with UIImage

Mert Kahraman
Mert Kahraman
12,118 Points

If let vs Guard Let

In the video we indicated this method:

func icon() -> UIImage {
    if let image = UIImage(named: self.rawValue) {
        return image
    } else {
        return UIImage(named: "Default")!
    }
}

Why did we use if let rather than guard let? Couldn't we write it as:

func icon() -> UIImage {
    guard let image = UIImage(named: self.rawValue) {
        return image
    } else {
         return UIImage(named: "Default")!
    }
}

If not, then why? I would appreciate your help.

Thanks

2 Answers

Steven Deutsch
Steven Deutsch
21,046 Points

Hey Mert Kahraman,

No this use of the guard statement does not compile as you have written it. Yes it is possible to use a guard statement to perform optional binding, however, its behavior is a little bit different than if let optional binding.

You can think of a guard statement as the reverse of an if let statement. With a guard statement we are making sure a condition is true, if it is not we immediately perform the else clause. With an if let statement, we are binding an optional to a local constant, if the bind succeeds... we immediately perform the success clause.

The problem with your code:

func icon() -> UIImage {
    guard let image = UIImage(named: self.rawValue) {
        return image
    } else {
         return UIImage(named: "Default")!
    }
}

The else clause should immediately follow the guard. This means the name of the constant being used to bind the optional value can not be used inside of that else block.

func icon() -> UIImage {
    guard let image = UIImage(named: "Photo") else {
        return UIImage(named: "Default")!
    }
    return image
}

Another option is using the nil coalescing operator:

func icon() -> UIImage {
    return UIImage(named: "Photo") ?? UIImage(named: "Default")!
}

Good Luck

There is a mistake of usage on your guard code.

func icon() -> UIImage {
  guard let image = UIImage(named: "Photo") else {
    return UIImage(named: "Default")!
  }
  return image
}

I prefer to use guard instead of if let. Guard is introduced with Swift 2.0. But in some conditions if let is better to use.