protocolsswiftconditional-binding

Bound value in a conditional binding must be of Optional Type


I have a protocol defined:

protocol Usable {
    func use()
}

and a class that conforms to that protocol

class Thing: Usable {
    func use () {
        println ("you use the thing")
    }
}

I would like to programmatically test whether or not the Thing class conforms to the Usable protocol.

let thing = Thing()

// Check whether or not a class is useable
if let usableThing = thing as Usable { // error here
    usableThing.use()
}
else {
    println("can't use that")
}

But I get the error

Bound value in a conditional binding must be of Optional Type

If I try

let thing:Thing? = Thing()

I get the error

Cannot downcast from 'Thing?' to non-@objc protocol type 'Usable'

I then add @objc to the protocol and get the error

Forced downcast in conditional binding produces non-optional type 'Usable'

At which point I add ? after the as, which finally fixes the error.

How can I achieve this functionality with conditional binding with a non-@objc protocol, the same as in the "Advanced Swift" 2014 WWDC Video?


Solution

  • You can get it to compile by making the cast as Usable? instead of as Usable, like this:

    // Check whether or not a class is useable
    if let usableThing = thing as Usable? { // error here
        usableThing.use()
    }
    else {
        println("can't use that")
    }