Swift协议比较

时间:2015-09-04 20:44:40

标签: swift swift2

我在使用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)) 的情况下完成吗?

1 个答案:

答案 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自动导入的未经过可空性审核的内容中复制了它。如果你知道它不能为零,那么使用类型。如果它可以为零,请使用可选项。很少有理由通过!