私はプロトコルを定義しています:
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以外のプロトコルを使用した条件付きバインディングでこの機能を実現するにはどうすればよいですか?
キャストを使用可能にすることでコンパイルできますか?次のように、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")
}
これは遊び場で私のために働きます
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")
}
Swift docで言及されているように、is
演算子はあなたが仕事に必要な人です:
Is演算子は、実行時に式が指定されたタイプかどうかを確認します。もしそうなら、それはtrueを返します。それ以外の場合は、falseを返します。
チェックは、コンパイル時にtrueまたはfalseであることを認識してはなりません。
したがって、通常、次のテストが必要です。
if thing is Usable {
usableThing.use()
} else {
println("can't use that")
}
ただし、ドキュメントで指定されているように、Swiftはコンパイル時に式が常にtrueであることを検出でき、開発者を支援するためにエラーを宣言します。
Swiftプロトコルは最初のベータのプレイグラウンドでは機能しません。代わりに実際のプロジェクトをビルドしてみてください。
あなたは得ています
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")
}