Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binary operator '~=' cannot be applied to operands of type 'String' and 'String?'

I have a simple switch-statement that is not that simple.

switch(bubble?.name){ //bubble is SKPhysicsBody
    case "largeBubble": // <= error
        newBubbleSize = "medium"
        break;
    default:
        newBubbleSize = "large"
        break;
}

Here I get error that I mentioned in title Binary operator '~=' cannot be applied to operands of type 'String' and 'String?'. And I have no clue why it is a problem that one of them is an optional.

like image 257
Jurik Avatar asked May 30 '15 18:05

Jurik


3 Answers

Because of Optional Chaining, bubble?.name has type String?. You have a few options:

  • Use "largeBubble"? in your case expression (Swift 2+ only).
  • Check for nil before doing your switch, so the switch argument will be a String instead of String?.
  • Use bubble!.name (or bubble.name if it's a SKPhysicsBody!) if you are absolutely sure that it won't be nil
like image 184
jtbandes Avatar answered Nov 07 '22 22:11

jtbandes


As @jtbandes said, the problem is the result of bubble?.name having type String?. An alternative solution, to the ones given, is to override the ~= operator to take a String? and String as arguments, for example:

func ~= (lhs: String, rhs: String?) -> Bool {
    return lhs == rhs
}

Or, to make it more generic:

func ~= <T: Equatable>(lhs: T, rhs: T?) -> Bool {
    return lhs == rhs
}
like image 32
ABakerSmith Avatar answered Nov 07 '22 23:11

ABakerSmith


“Values are never implicitly converted to another type. If you need to convert a value to a different type, explicitly make an instance of the desired type.”

“let label = "The width is "
let width = 94
let widthLabel = label + String(width)”

Here width is an Integer type it has been converted to String by String(Int) function

like image 40
Pias Avatar answered Nov 07 '22 22:11

Pias