What is wrong with my if statement?

I'm attempting to write a simple function that will print "B" for any grades in the range of 80 and 89. I wrote the code below with a switch statement and it worked just fine:

func determineGrades(test score: Int) {

    switch score {
    case (80...89):
       print("B")
    default:
        print("Awaiting Score")
    }
}

determineGrades(test: 88)

But when I tried to write a function with the same criteria using an if statement, instead of a switch statement, I could not get it to work. I wrote the code below:

 func determineGrades2(grade testScore: Int) {
 
    let bGrades = (80...89)
    
   if testScore == bGrades {
       print("B")
   }
 }
 
 determineGrades2(grade: 88)

Could someone please help me to understand what I did wrong here with the if Statement? Please help. Thank you!

switch does not compare == between its cases, but instead uses ~= which is a more powerful “pattern matching comparison”

So the equivalent if block would be

if (80...89) ~= testScore {
  print("B")
} else {
  // Don’t forget default case!
  print("Awaiting Score")
}

Why does it do this? Remember that you’re switching an Int against a Range, which is never equal in a strict sense. What switch wants is to do a more lenient comparison Does testScore match pattern bGrade?.

The side effect of this is that you can add your own pattern matching ~= operator and have it supported by switch. I’m sure Int and Range in your example does this under the hood.

For more information, there’s a section in swift book regarding pattern matching Here.

1 Like

~= is what a switch statement calls through to when you match a value against a range. For Range, the implementation of the ~= operator calls through to Range.contains(_:).

It is pretty rare for Swift code to use the ~= operator outside of its implicit usage in switch. Most people would write the if statement for your logic as if (80..89).contains(testScore) {

1 Like

Thank you for explaining this, this was really helpful!

Thank you, Benjamin!

You can also write:

if case 80...89 = testScore { ... }
1 Like