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

4

7

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.

Mcadams answered 30/5, 2015 at 18:9 Comment(0)
S
8

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
Saidee answered 30/5, 2015 at 18:13 Comment(6)
Option #4: switch(bubble?.name ?? "unknown") { ... }.Brandish
Sure, but then you will be doing an unnecessary comparison with the string "unknown" in some cases :) Of course, it's probably so fast that it doesn't matter...Saidee
bubble!.name didn't work - well, only in combination with some(). Thought that's why there's always a default as well ... if name is not set.Mcadams
@Mcadams exactly what type is bubble? (SKPhysicsBody or SKPhysicsBody? or perhaps !)Saidee
It's bodyA or bodyB from SKPhysicsContact.Mcadams
bodyA and bodyB are both SKPhysicsNode!. I am not 100% sure, but I suspect these are really never nil, so it's safe to just use bubble.name. That is the solution I would recommend.Saidee
E
3

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
}
Endometrium answered 30/5, 2015 at 18:19 Comment(1)
Equatable would be sufficient :)Brandish
M
1

“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

Morry answered 19/9, 2015 at 8:45 Comment(0)
V
0

In Swift 2.0 (sender: UIButton) then ! for the switch string works.

let operation = sender.currentTitle!

In Swift 2.0, (sender: AnyObject) then !! for the switch string works.

let operation = sender.currentTitle!!

the mistake which i made is using AnyObject instead of UIButton.

@IBAction func operate(sender: AnyObject) {
        let operation = sender.currentTitle!!

        if userIsInTheMiddleOfTypeingNumber{
            enter()
        }

        switch operation{
            case "×":
                if operandStack.count >= 2{
                    displayValue = operandStack.removeLast() * operandStack.removeLast()
                }

                break
//            case "÷":
//                break
//            case "+":
//                break
//            case "−":
//                break
           default:
                break
        }

    }
Vinnievinnitsa answered 24/9, 2015 at 5:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.