19

我定义了一个协议:

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,最终修复了错误。

如何通过非@objc 协议的条件绑定来实现此功能,与“Advanced Swift”2014 WWDC Video 中的相同?

4

5 回答 5

33

您可以通过将演员表设为可用来编译它吗?而不是作为可用,像这样:

// Check whether or not a class is useable
if let usableThing = thing as Usable? { // error here
    usableThing.use()
}
else {
    println("can't use that")
}
于 2014-06-08T21:39:49.587 回答
1

正如 Swift 文档中提到的那样,is操作员是您完成这项工作所需的人:

is 运算符在运行时检查表达式是否属于指定类型。如果是,则返回 true;否则,它返回 false。

在编译时不能知道检查是真还是假。

因此,通常需要以下测试:

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

但是,正如文档所指定的那样,Swift 可以在编译时检测到表达式始终为真并声明错误以帮助开发人员。

于 2014-06-08T23:09:09.137 回答
1

这在操场上对我有用

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")
}
于 2014-06-17T09:20:26.847 回答
0

swift 协议在第一个 beta 版的 Playgrounds 中不起作用,请尝试构建一个真实的项目。

于 2014-06-09T11:18:15.333 回答
0

你得到

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")
}
于 2014-06-08T22:37:39.783 回答