【发布时间】:2019-03-17 21:18:14
【问题描述】:
我正在尝试使具有关联值的枚举符合 CaseIterable、RawRepresentable。在用 rawValue 初始化时,我对关联值的一些默认值很好。
enum GenresAssociated: CaseIterable, RawRepresentable, Equatable {
case unknown(String)
case blues(String)
case classical(String)
// Implementing CaseIterable
typealias AllCases = [GenresAssociated]
// Enums can have no storage, but the class they are in CAN. Note 'static' in declaration
static var allCases: [GenresAssociated] = [.unknown(""), .blues(""), .classical("")]
typealias RawValue = Int
var rawValue: Int {
// MARK: This causes a crash for unknown reason
return GenresAssociated.allCases.firstIndex(where: { if case self = $0 { return true } else { return false } } ) ?? 0
}
init?(rawValue: Int) {
guard GenresAssociated.allCases.indices.contains(rawValue) else { return nil }
self = GenresAssociated.allCases[rawValue]
}
}
有什么方法可以在所有情况下不手动切换,即没有这样的代码:
typealias RawValue = Int
var rawValue: Int {
switch self {
case .unknown:
return 0
case .blues:
return 1
case .classical:
return 2
}
}
值得注意的是,非常相似的代码也可以正常工作,例如
enum EnumWithValue {
case one(NSString!), two(NSString!), three(NSString!)
}
let arrayOfEnumsWithValues: [EnumWithValue] = [.one(nil), .two(nil), .three("Hey")]
if let index = arrayOfEnumsWithValues.firstIndex(where: { if case .two = $0 { return true }; return false }) {
print(".two found at index \(index)") //prints ".two found at index 1"
}
【问题讨论】:
-
我不会在具有关联值的枚举上使用
RawRepresentable,正如RawRepresentable协议所表明的那样,您可以“在自定义类型和关联的 RawValue 类型之间来回切换而不会丢失原始 RawRepresentable 类型的值” (developer.apple.com/documentation/swift/rawrepresentable)。这意味着您的关联值也以某种方式包含在rawValue中。 -
完全同意,@Palle。数据结构是一种 kext(也是 Enum 的压力测试)。是的,我在这里玩 Enums,试图掌握它们。