我定义了一个协议:
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协议进行条件绑定来实现此功能,与“高级Swift”2014 WWDC视频中的相同?
答案 0 :(得分: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")
}
答案 1 :(得分:1)
正如Swift文档中所提到的,is
运算符就是你需要的人:
is运算符在运行时检查表达式是否为 指定的类型。如果是,则返回true;否则,它返回 假的。
在编译时,检查不得为真或假。
因此,以下测试通常是您所需要的:
if thing is Usable {
usableThing.use()
} else {
println("can't use that")
}
但是,正如doc指定的那样,Swift可以在编译时检测到表达式始终为true并声明错误以帮助开发人员。
答案 2 :(得分: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")
}
答案 3 :(得分: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")
}
答案 4 :(得分:0)
swift协议在第一个测试版的Playgrounds中不起作用,试着建立一个真正的项目。