【问题标题】:Inheritance Generic Protocols继承通用协议
【发布时间】:2017-03-22 23:03:29
【问题描述】:

我有 2 个协议继承自一个通用协议

protocol IdentifierProtocol: Equatable, RawRepresentable {}

protocol A_IdentifierProtocol: IdentifierProtocol {}
protocol B_IdentifierProtocol: IdentifierProtocol {}

我想使用函数进行拆分,但是这段代码出错了

extension UIClass {
    func myFunc<I: IdentifierProtocol>(identifier: I) where I.RawValue == String {
         if identifier is A_IdentifierProtocol { // <- Error
             print("A")
         }
         if identifier is B_IdentifierProtocol { // <- Error
             print("B")
         }
    }
}

错误:协议 'A_IdentifierProtocol' 只能用作通用约束,因为它具有 Self 或关联的类型要求

我该如何解决这个问题?

【问题讨论】:

  • 那么你得到的错误是什么?

标签: swift swift-protocols


【解决方案1】:

您的IdentifierProtocolRawRepresentable,其中有associatedType。而且这样的协议不能“像具体类型一样”使用。

这基本上就是编译错误所说的:

错误:协议 'A_IdentifierProtocol' 只能用作通用约束,因为它具有 Self 或关联的类型要求

建议您阅读有关您遇到的错误的说明,而不是重复信息:https://stackoverflow.com/a/36350283/2378431


如果您想解决此错误并且仍然让您的代码正常工作而没有任何明显差异(从使用角度来看),您可以为每个 X_IdentifierProtocol 定义一个方法,如下所示:

protocol IdentifierProtocol: Equatable, RawRepresentable {}

protocol A_IdentifierProtocol: IdentifierProtocol {}
protocol B_IdentifierProtocol: IdentifierProtocol {}

func myFunc<I: A_IdentifierProtocol>(identifier: I) where I.RawValue == String {
    print("A: \(identifier.rawValue)")
}

func myFunc<I: B_IdentifierProtocol>(identifier: I) where I.RawValue == String {
    print("B: \(identifier.rawValue)")
}

缺点是,对于每个X_IdentifierProtocol,您需要提供一个方法实现,如果您想拥有一段基于IdentifierProtocol 的共享代码,可能会引入一些代码重复。


另一种方法:如果您真的想要单个功能,则不能将 IdentifierProtocol 与关联类型联系起来。但是,您可以对泛型函数有多种类型约束,如下所示:

protocol IdentifierProtocol {}

protocol A_IdentifierProtocol: IdentifierProtocol {}
protocol B_IdentifierProtocol: IdentifierProtocol {}

func myFunc<I: IdentifierProtocol & Equatable & RawRepresentable>(identifier: I) where I.RawValue == String {
    if identifier is A_IdentifierProtocol {
        print("A: \(identifier.rawValue)")
    }
    if identifier is B_IdentifierProtocol {
        print("A: \(identifier.rawValue)")
    }
}

class MyClassA: A_IdentifierProtocol, RawRepresentable, Equatable {...}
class MyClassB: B_IdentifierProtocol, RawRepresentable, Equatable {...}

但即使这样也不是完美的,也不能完全满足您的要求。


底线是你无法用 Swift 3 完全实现你想要的。

【讨论】:

  • 我只想把很多方法合二为一。我使用泛型作为基本类型。这是定义关联类型
  • 看看,我添加了另一种方法,但仍然不是你想要的。 AFAIK 你无法用 Swift 3 完全实现你想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多