我在使用Swift中的Protocol类型执行类型检查时遇到了困难。我有一些协议(在obj-c框架中定义),我正在尝试检查它们的类型:
CurrentState(int state[][3]);
我试过了:
public func resolve(proto: Protocol!) -> NSObject {
// does not match when called with resolve(Foo)
if (proto is Foo)
{
return FooImpl();
}
// other type checking here
}
这可以在不使用// Compile error: Expected member name or constructor call after type name
if (proto === Foo)
// Compile error: Expected member name or constructor call after type name
if (proto == Foo)
// Works, but seems hackish as it reverts to string comparison
if (NSStringFromProtocol(proto) == NSStringFromProtocol(Foo))
的情况下完成吗?
答案 0 :(得分:4)
Protocol
是运行时类型,而不是对象。您需要在其上使用运行时函数。
public func resolve(proto: Protocol) -> NSObject {
if protocol_isEqual(proto, Foo.self) {
return FooImpl()
}
// other type checking here
}
那就是说,这几乎不是在Swift中做事的正确方法。如果你真的需要做这种工作,你应该使用重载:
func resolve(proto: Foo.Type) -> NSObject {
return FooImpl()
}
func resolve(proto: Any) -> NSObject {
return DefaultIfYouNeedOne()
}
斯威夫特会选择最好的超载。如果您没有Any
版本,那就更好了,因为Swift不允许您将意外类型传递给resolve
。
但即便如此,这通常表明你正在做一些你可能不应该做的事情。通常,如果您需要能够构建类,则应该只在协议中添加init()
。或者为您可以构建的事物(或Constructible
或您需要的任何内容)创建Resolvable
协议。专注于协议,而不是具体类型。当你发现自己做了很多类型检查时,你可能正在与Swift战斗。您可能必须要连接到ObjC,但不要创建更多。 Swift中几乎没有任何东西应该返回NSObject
。
无关注:您不应在新功能中使用Protocol!
。您可能从ObjC自动导入的未经过可空性审核的内容中复制了它。如果你知道它不能为零,那么使用类型。如果它可以为零,请使用可选项。很少有理由通过!
。