从Any转向协议

时间:2014-06-19 05:52:45

标签: ios swift

我有以下代码。如何在最后一行解决错误?

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

4 个答案:

答案 0 :(得分:13)

更新:已在Swift 1.2+(Xcode 6.3+)中修复此问题。 Xcode 6.3测试版发行说明:

  

动态演员表(“as!"”,作为?"和“是”)现在可以使用Swift协议   类型,只要它们没有相关的类型。


您只能使用 is协议检查协议一致性(包括asas?@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等。