检查类是否符合协议

Pet*_*lom 7 swift

我试图在swift中为我们的应用程序创建一个简单的依赖注入系统,现在为期2天.我对任何解决方案都很灵活,但我想要一些东西,所以我可以说"给我一个符合这个协议的东西的实例",只要它符合上述协议,返回的实际类型就可以是任何东西.我已经尝试了很多东西,包括泛型,但设法弄清楚那不能(?)真的有用,所以现在我已经完成了基本的工作,如下所示:

protocol AProtocol {

}

class AClass: AProtocol {

} 

class MyDiThing {
    public static func objectConformingTo(aProtocol: Any) -> Any? {
        // And here I want to do something like
        if AClass is aProtocol {
            return AClass()
        }
        return nil
    }
}

// The calling code ..
let aObject = MyDIThing.objectConformingTo(AProtocol)
Run Code Online (Sandbox Code Playgroud)

我知道,它并不漂亮,但是现在我不是那么挑剔性能/坏代码,只要它解决了解耦问题(最好能包含在MyDIThing类中).如果这是不可能的,我会对其他解决方案持开放态度.我使用了类似于objective-c的解决方案并取得了很好的成功,只需要一个字典,其中键是NSStringFromProtocol,值是类,使用入站协议下载字典并实例化类.超级简单.很快就感觉不可能!

auc*_*uco 8

nhgrif给出的注释是Swift 2的正确答案.您应该使用可选的绑定:

if let aObjectWithAProtocol = aObject as? AProtocol {
    // object conforms to protocol
    someObject.someFunction(aObjectWithAProtocol)
} else {
    // object does not conform to protocol
}
Run Code Online (Sandbox Code Playgroud)

if let something = obj as? type语句称为可选绑定,并检查对象是否可以类型转换为给定类型/ class/protocol/....

如果是这样,您可以使用optional(as?)或强制unwrap(as!)对象.


Wai*_*ain 3

如果你导入 obj-c 那么你可以像以前一样做一些事情。

否则,这会很困难,因为协议不以同样的方式存在。考虑为您的工厂建立一个基于注册的系统。每个类都将通过提供一个函数或闭包来注册自己,可以调用该函数或闭包来返回该类的新实例,并且注册是针对字符串或某种其他类型的标识符。这是最好有一个协议类型的地方,但在 obj-c 中,你实际上是通过字符串转换做同样的事情。您可以注册任何使Equatable事情变得非常通用的东西。

  • `如果让 foo = bar 作为?MyProtocol { /* bar 符合协议... foo 是 MyProtocol 类型,可以在其上调用方法 */ }` (8认同)