符合具有关联类型的协议的枚举类型数组
Array of enum types conforming to a protocol with an associated type
让我们考虑一个简化的情况,两个枚举类型符合 CaseIterable
。
enum A: String, CaseIterable {
case a1, a2, a3
}
enum B: String, CaseIterable {
case b1, b2, b3
}
我想要做的是创建某种散列 table 关联一个键(在我的例子中是一个字符串)和枚举的 类型 :
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
]
我最终需要实现的是 "query" 我的散列 table 用于特定密钥,并对结果应用协议方法(比如 allCases
)。
let cases = dict["my key A"]!.allCases
有什么建议吗?
I want to display a menu listing all the possible options.
所以你需要字符串,而不是案例本身。这是绝对可行的。首先,首先说明您真正希望该类型以协议的形式执行的操作:
protocol CaseNamed {
static var caseNames: [String]
}
如果你有,你可以构建你想要的:
var enums: [CaseNamed.Type] = [A.self, B.self]
enums.flatMap { [=11=].caseNames }
(我称之为 "wish driven development." 我希望我有一个类型可以....)
现在您只需要通过实施 caseNames
使类型符合 CaseNamed。幸运的是,如果类型也恰好符合 CaseIterable:
extension CaseNamed where Self: CaseIterable {
static var caseNames: [String] {
self.allCases.map { "\([=12=])" }
}
}
但是您可以使用不符合 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 { "\([=13=])" }
}
}
var enums: [CaseNamed.Type] = [A.self, B.self]
enums.flatMap { [=13=].caseNames }
当然,您可能还希望此 CaseNamed 协议执行其他操作,因此您可以添加其他操作。但是您需要考虑调用代码以及它完成其工作的根本需要。
让我们考虑一个简化的情况,两个枚举类型符合 CaseIterable
。
enum A: String, CaseIterable {
case a1, a2, a3
}
enum B: String, CaseIterable {
case b1, b2, b3
}
我想要做的是创建某种散列 table 关联一个键(在我的例子中是一个字符串)和枚举的 类型 :
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
]
我最终需要实现的是 "query" 我的散列 table 用于特定密钥,并对结果应用协议方法(比如 allCases
)。
let cases = dict["my key A"]!.allCases
有什么建议吗?
I want to display a menu listing all the possible options.
所以你需要字符串,而不是案例本身。这是绝对可行的。首先,首先说明您真正希望该类型以协议的形式执行的操作:
protocol CaseNamed {
static var caseNames: [String]
}
如果你有,你可以构建你想要的:
var enums: [CaseNamed.Type] = [A.self, B.self]
enums.flatMap { [=11=].caseNames }
(我称之为 "wish driven development." 我希望我有一个类型可以....)
现在您只需要通过实施 caseNames
使类型符合 CaseNamed。幸运的是,如果类型也恰好符合 CaseIterable:
extension CaseNamed where Self: CaseIterable {
static var caseNames: [String] {
self.allCases.map { "\([=12=])" }
}
}
但是您可以使用不符合 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 { "\([=13=])" }
}
}
var enums: [CaseNamed.Type] = [A.self, B.self]
enums.flatMap { [=13=].caseNames }
当然,您可能还希望此 CaseNamed 协议执行其他操作,因此您可以添加其他操作。但是您需要考虑调用代码以及它完成其工作的根本需要。