Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以在Swift中将元类对象强制转换为协议类型吗?_Swift_Metaclass - Fatal编程技术网

我可以在Swift中将元类对象强制转换为协议类型吗?

我可以在Swift中将元类对象强制转换为协议类型吗?,swift,metaclass,Swift,Metaclass,Swift继承了Objective-C的元类概念:类本身也被视为对象。类Foo对象的类是Foo.self,它的类型是Foo.type。如果Foo继承自Bar,则Foo.self也可以分配给Bar.type类型的变量。这至少有两个好处: 它允许覆盖“静态方法” 以类型安全的方式创建未知类的实例很容易,而且不需要使用反射 我现在特别关注第二个。为了确保每个人都理解我的目的,这里有一个例子: class BaseFoo { var description: String { return

Swift继承了Objective-C的元类概念:类本身也被视为对象。类
Foo
对象的类是
Foo.self
,它的类型是
Foo.type
。如果
Foo
继承自
Bar
,则
Foo.self
也可以分配给
Bar.type
类型的变量。这至少有两个好处:

  • 它允许覆盖“静态方法”
  • 以类型安全的方式创建未知类的实例很容易,而且不需要使用反射
我现在特别关注第二个。为了确保每个人都理解我的目的,这里有一个例子:

class BaseFoo {
    var description: String { return "BaseFoo" }
}

class DerivedFoo: BaseFoo {
    override var description: String { return "DerivedFoo" }
}

let fooTypes: [BaseFoo.Type] = [BaseFoo.self, DerivedFoo.self] // metaclass magic!
for type in fooTypes {
    let object: BaseFoo = type() // metaclass magic!
    println(object)
}
现在,我有了一个
AnyClass
对象数组(任何元类实例都可以分配给
AnyClass
,就像任何对象都可以分配给
AnyObject
),我想找出哪些实现了给定的协议。协议将声明一个初始值设定项,我将像在上面的示例中一样实例化该类。例如:

protocol Foo {
    init(foo: String)
}

class Bar: Foo {
    required init(foo: String) { println("Bar initialized with \(foo)") }
}

class Baz {
    required init() { println("I'm not a Foo!") }
}

let types: [AnyClass] = [Bar.self, Baz.self]
到目前为止还不错。现在,问题是确定类是否实现了该协议。由于元类实例是多态的,所以我希望能够对它们进行强制转换。然而,我显然遗漏了一些东西,因为斯威夫特不让我写这个:

for type in types {
    if let fooType = type as? Foo.Type {
        let obj = fooType(foo: "special snowflake string")
    }
}
我得到的编译器错误是:

错误:“Foo”与“AnyObject”不同

有没有办法确定元类实例是否表示实现协议的类,有没有办法将该实例强制转换为协议类型

我试图将
Foo
声明为类协议,但这显然是不够的



编辑:我刚刚尝试了
任何
类型,虽然它不会导致语法错误,但会使Swift编译器崩溃。

从Xcode 7 beta 2和Swift 2开始,它已经被修复。你现在可以写:

for type in types {
    if let fooType = type as? Foo.Type {
        // in Swift 2 you have to explicitly call the initializer of metatypes
        let obj = fooType.init(foo: "special snowflake string")
    }
}
或者,如果您只想将
type
作为type
Foo.type
使用,您可以将
用于case

for case let type as Foo.Type in types {
    let obj = type.init(foo: "special snowflake string")
}

使编译器崩溃了。耶!至于实际问题,我不确定元类在当前的Swift中是否可以内省。至少,如果我使用基类而不是协议,它是有效的。有同样的问题:(查看我的SO问题: