关联值符合CaseIterable,RawRepresentable的枚举 [英] Enum with associated value conforming to CaseIterable, RawRepresentable
本文介绍了关联值符合CaseIterable,RawRepresentable的枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试使具有关联值的枚举符合CaseIterable,RawRepresentable。使用rawValue初始化时,我可以为关联值使用一些默认值。
I'm trying to make enum with associated value conform to CaseIterable, RawRepresentable. I'm fine with some default values for associated values when initializing by 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]
}
}
有没有办法通过手动切换所有情况下,即没有这样的代码:
Is there any way to make it without switching manually by all the cases, i.e. without such code:
typealias RawValue = Int
var rawValue: Int {
switch self {
case .unknown:
return 0
case .blues:
return 1
case .classical:
return 2
}
}
值得注意的是,非常相似的代码也很好用,例如
What's notable is that very similar code works just fine, for example
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"
}
推荐答案
我终于可以使用 Mirror
!
var rawValue: Int {
let selfCaseName = Mirror(reflecting: self).children.first!.label!
return GenresAssociated.allCases.firstIndex(where: { (genre) in
let switchingCaseName = Mirror(reflecting: genre).children.first!.label!
return switchingCaseName == selfCaseName
})!
}
不要介意展开力,在这里很安全。
Don't mind the force unwrapping, it is safe here.
这篇关于关联值符合CaseIterable,RawRepresentable的枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文