Перечисление со связанным значением, соответствующим CaseIterable, RawRepresentable - PullRequest
1 голос
/ 18 марта 2019

Я пытаюсь привести enum со связанным значением в 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"
}

1 Ответ

1 голос
/ 18 марта 2019

Наконец-то я смог работать с 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
    })!
}

Не возражайте против разворачивания силы, здесь безопасно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...