case let immediately precedes the candidate pattern in both versions. Confusingly though, when using if case let, the value comes after the = operator. So
if case let Puppy.mastiff(droolRating, weight) = fido {
is equivalent to:
switch fido {
case let Puppy.mastiff(droolRating, weight):
// tell fido he's a good doggo
case let is a shortcut that lets you bind all subsequent associated values with just variable names. But you can write each let individually, just before the variable name:
if case Puppy.mastiff(let droolRating, let weight) = fido {
// does that pup need an extra treat?
Provide a single name to create a tuple of all associated values at once:
if case let Puppy.mastiff(characteristics) = fido {
// how cute is this doggo, exactly?
The ? is syntactic sugar to only match non-nil optionals:
if case let Puppy.mastiff(droolFactor, weight) ? = potentialPup {
// oh thank goodness, a puppy
Omit let entirely if you don't need the associated values:
if case Puppy.mastiff = fido {
// just hand me the pupster
if case let Puppy.mastiff(droolRating, _) = fido, droolRating > 8 {
// you're going to need a new couch
guard case let Puppy.mastiff(droolRating, _) = fido, droolRating < 10 else {
// that dog is not coming in the house
for case let Puppy.mastiff(droolRating, weight) in rescuePups where droolRating > 5 && weight > 15.0 {
// I'll take the chubby, soggy ones please
Use ? to iterate over just non-optional values, even when doubly nested in associated values:
for case let SocialMedia.instagram(linkInBio?)? in pups.map(\.socialMedia) {
// all the links please
Really helpful if you need one non-optional assignment amidst a bunch of optional ones:
if let rescueCenter = nearest(), case let puppies = rescueCenter.puppies, puppies.count < 10 {
// better hurry or might not get enough
Other more in-depth articles: