我可以在Swift中将元类对象转换为协议类型吗? [英] Can I cast a metaclass object to a protocol type in Swift?

查看:79
本文介绍了我可以在Swift中将元类对象转换为协议类型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Swift inherited Objective-C's metaclass concept: classes themselves are also considered objects. A class Foo's object's class is Foo.self, and it is of type Foo.Type. If Foo inherits from Bar, then Foo.self can be assigned to a variable of type Bar.Type, too. This has at least two benefits:

  • 它允许覆盖静态方法";
  • 很容易以类型安全的方式创建未知类的实例,而无需使用反射.

我现在正在特别关注第二个.为了确保每个人都明白我的追求,下面是一个示例:

I'm particularly looking at the second one right now. Just to be sure that everybody understands what I'm after, here's an example:

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一样),我想找出哪些对象可以实现给定的协议.该协议将声明一个初始化程序,就像在上面的示例中一样,我将实例化该类.例如:

Now, I have an array of AnyClass objects (any metaclass instance can be assigned to AnyClass, just like any object can be assigned to AnyObject), and I want to find which ones implement a given protocol. The protocol would declare an initializer, and I would instantiate the class just like I do in the example above. For instance:

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]

到目前为止,一切都很好.现在,问题在于确定该类是否实现了该协议.由于元类实例是多态的,所以我希望能够将其强制转换.但是,我显然缺少了一些东西,因为Swift不允许我这样写:

So far so good. Now, the problem is determining if the class implements the protocol. Since metaclass instances are polymorphic, I'd expect to be able to cast them. However, I'm apparently missing something, because Swift won't let me write this:

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

我得到的编译器错误是:

The compiler error I get is:

错误:"Foo"与"AnyObject"不同

error: 'Foo' is not identical to 'AnyObject'

是否有任何方法可以确定元类实例是否代表实现协议的类,并且有任何方法可以将该实例转换为协议类型?

Is there any way to determine if a metaclass instance represents a class that implements a protocol, and is there any way to cast that instance into a protocol type?

我试图将Foo声明为类协议,但显然还不够.

I tried to declare Foo as a class protocol, but it's apparently not enough.

编辑:我只是尝试使用Any类型,尽管它不会引起语法错误,但它会使Swift编译器崩溃.

EDIT: I just tried with the Any type, and while it doesn't cause a syntax error, it crashes the Swift compiler.

推荐答案

从Xcode 7 beta 2和Swift 2开始,它已得到修复.您现在可以编写:

As of Xcode 7 beta 2 and Swift 2 it has been fixed. You can now write:

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作为类型Foo.Type,则可以使用for case

Or if you only want type as type Foo.Type you can use for case

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

这篇关于我可以在Swift中将元类对象转换为协议类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆