web-dev-qa-db-ja.com

条件付きバインディングのバインドされた値は、オプションタイプである必要があります

私はプロトコルを定義しています:

protocol Usable {
    func use()
}

そしてそのプロトコルに準拠するクラス

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

ThingクラスがUsableプロトコルに準拠しているかどうかをプログラムでテストしたいと思います。

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")
}

しかし、私はエラーが出ます

Bound value in a conditional binding must be of Optional Type

私がしようとすると

let thing:Thing? = Thing()

エラーが出る

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

次に、@objcをプロトコルに追加してエラーを取得します

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

その時点で、asの後に?を追加し、最終的にエラーを修正します。

「Advanced Swift」2014 WWDCビデオと同じように、@ objc以外のプロトコルを使用した条件付きバインディングでこの機能を実現するにはどうすればよいですか?

19
JuJoDi

キャストを使用可能にすることでコンパイルできますか?次のように、Usableの代わりに:

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

これは遊び場で私のために働きます

protocol Usable {
    func use()
}

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

let thing = Thing()
let testThing : AnyObject = thing as AnyObject

if let otherThing = testThing as? Thing {
    otherThing.use()
} else {
    println("can't use that")
}
1
David Arve

Swift docで言及されているように、is演算子はあなたが仕事に必要な人です:

Is演算子は、実行時に式が指定されたタイプかどうかを確認します。もしそうなら、それはtrueを返します。それ以外の場合は、falseを返します。

チェックは、コンパイル時にtrueまたはfalseであることを認識してはなりません。

したがって、通常、次のテストが必要です。

if thing is Usable { 
    usableThing.use()
} else {
    println("can't use that")
}

ただし、ドキュメントで指定されているように、Swiftはコンパイル時に式が常にtrueであることを検出でき、開発者を支援するためにエラーを宣言します。

1
Jean Le Moignan

Swiftプロトコルは最初のベータのプレイグラウンドでは機能しません。代わりに実際のプロジェクトをビルドしてみてください。

0
user3722125

あなたは得ています

Bound value in a conditional binding must be of Optional Type

thing as Usableはオプションの型を返す必要があるので、それをas?は問題を解決するはずです。残念ながら、エラーは依然としていくつかの奇妙な理由で持続しました。とにかく、私がそれを機能させるために見つけた回避策は、ifステートメント内の変数割り当てを抽出することです

let thing = Thing()

let usableThing = thing as? Usable

if useableThing { 
    usableThing!.use()
}
else {
    println("can't use that")
}
0
Infinity