【问题标题】:Array of enum types conforming to a protocol with an associated type符合具有关联类型的协议的枚举类型数组
【发布时间】:2020-05-24 00:40:55
【问题描述】:

让我们考虑一个简化的情况,有两个符合CaseIterable 的枚举类型。

enum A: String, CaseIterable {
    case a1, a2, a3
}

enum B: String, CaseIterable {
    case b1, b2, b3
}

我想做的是创建某种哈希表,将键(在我的示例中为字符串)和枚举的 type 关联起来:

let dict: [String : CaseIterable.Type] = [ // Error here: Protocol 'CaseIterable' can only be used as a generic constraint because it has Self or associated type requirements
    "my key A" : A.self,
    "my key B" : B.self
]

我最终需要实现的是“查询”我的哈希表以获取特定键并对结果应用协议方法(例如allCases)。

let cases = dict["my key A"]!.allCases

有什么建议吗?

【问题讨论】:

  • 这里编译器抱怨的关联类型是枚举本身,所以在你的情况下是 A 和 B。
  • 您希望cases 是什么(静态,在编译时已知)类型?这是“一些未知枚举的情况”,那么你会如何处理这个变量呢?您对这些案例是什么或您可以调用哪些方法一无所知。如果您显示您将如何处理 cases 的代码,那么这将显示您打算使用的实际协议(而不是 CaseIterable)
  • 为您的案例分配相同的字符串值是没有意义的
  • @Rob Napier:所有枚举在编译时都是已知的。每个枚举都描述了不同的情况,因此每个枚举都有不同的情况。我需要使用的实际协议是“CaseIterable”——我想显示一个列出所有可能选项的菜单。
  • @Leo Dabus:不是没有意义,只是一个例子,字符串值与问题无关。

标签: swift protocols hashtable


【解决方案1】:

我想显示一个列出所有可能选项的菜单。

所以你想要的是字符串,而不是案例本身。这是绝对可行的。首先,首先说明你真正希望类型以协议的形式做什么:

protocol CaseNamed {
    static var caseNames: [String]
}

如果你有这个,你可以构建你想要的:

var enums: [CaseNamed.Type] = [A.self, B.self]
enums.flatMap { $0.caseNames }

(我称之为“愿望驱动的开发”。我希望我有一种可以......)

现在您只需通过实现caseNames 使类型符合 CaseNamed。幸运的是,如果该类型也恰好符合 CaseIterable,这很容易:

extension CaseNamed where Self: CaseIterable {
    static var caseNames: [String] {
        self.allCases.map { "\($0)" }
    }
}

但是您可以拥有不符合 CaseIterable 的 CaseNamed 类型。 CaseIterable 不是必需的。如果你有它就好了。这是完整的代码:

protocol CaseNamed {
    static var caseNames: [String] { get }
}

enum A: String, CaseIterable, CaseNamed {
    case a1, a2, a3
}

enum B: String, CaseIterable, CaseNamed {
    case b1, b2, b3
}

extension CaseNamed where Self: CaseIterable {
    static var caseNames: [String] {
        self.allCases.map { "\($0)" }
    }
}

var enums: [CaseNamed.Type] = [A.self, B.self]

enums.flatMap { $0.caseNames }

当然,现在您可能还希望此 CaseNamed 协议执行其他操作,因此您可以添加其他操作。但是您需要从调用代码的角度来思考,以及它从根本上需要什么来完成它的工作。

【讨论】:

    猜你喜欢
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-02
    • 2020-11-10
    • 1970-01-01
    相关资源
    最近更新 更多