我有以下代码。如何在最后一行解决错误?
protocol Animal {
func walk()
}
struct Cat: Animal {
func walk() {}
init() { }
}
var obj: Any = Cat()
var cat = obj as Animal // ERROR: cannot downcast from Any to unrelated type Animal
答案 0 :(得分:13)
更新:已在Swift 1.2+(Xcode 6.3+)中修复此问题。 Xcode 6.3测试版发行说明:
动态演员表(“as!"”,作为?"和“是”)现在可以使用Swift协议 类型,只要它们没有相关的类型。
您只能使用 is
协议检查协议一致性(包括as
,as?
和@objc
)。 Animal
不是@objc
。
请参阅Swift书的Checking for Protocol Conformance部分。
请注意
只有标记了协议,才能检查协议一致性 使用@objc属性
答案 1 :(得分:3)
您可以通过执行
来解决此问题 var cat = obj as Cat as Animal
但是这种解决方法几乎没用......因为你需要首先知道obj
的类型
编辑:
正如@newacct指出的那样,它不是bug,请参阅他的答案以获取更多信息
xcrun swift
Welcome to Swift! Type :help for assistance.
1>
2> @objc protocol Animal {
3. func walk()
4. }
@objc class Cat: Animal {
func walk() {}
init() { }
}
var obj: AnyObject = Cat()
var cat = obj as Animal
5>
6> @objc class Cat: Animal {
7. func walk() {}
8.
9. init() { }
10. }
11>
12> var obj: AnyObject = Cat()
obj: Cat = {}
13>
14> var cat = obj as Animal
cat: Cat = {}
15>
Animal
协议需要@objc
属性,Cat
需要@objc class
。
答案 2 :(得分:0)
我的方法
@objc protocol Animal {
func walk()
}
@objc class DummyAnimal: Animal {
func walk() {
}
}
@objc class Cat: DummyAnimal {
override func walk() {
print("meow")
}
override init() { }
}
var obj: Any = Cat()
var cat = obj as DummyAnimal
cat.walk()
答案 3 :(得分:-1)
据我所知,AnyObject
只能 向下转换 到类类型(†)和{{1}的实例只能 向下转换 到类型(类或其他), 强制转换 它们不能用于协议
我不知道我是否会将其视为一个或多个错误,如果这样,那么也许它是以这种方式实现的有充分理由 - 但是@Bryan的解决方法(首先转换为类型然后转换为协议)至少“解决了错误”!
(†)值得注意的例外包括能够从AnyObject向下转换为核心数据类型Int,String等。