Общая функция для получения индекса перечисления case из allCases - PullRequest
1 голос
/ 17 апреля 2019

У меня есть класс со свойством, которое является случаем из Enum.Я хочу написать обобщенную функцию, чтобы получить индекс регистра в Enum allCases.

Я начинаю с определения протокола HasEnumCase, в котором просто говорится, что у приемных пользователей есть связанный тип CaseIterable & Equatable.

protocol HasEnumCase {
    associatedtype TheEnum: CaseIterable & Equatable
    var theCase: TheEnum { get }
}

Это не компилируется.

func getIndexInAllCases<T: HasEnumCase>(theInstance: T) -> Int {
    let allCases = T.TheEnum.allCases
    let index = allCases.firstIndex(of: theInstance.theCase)
    return index
}

//Cannot convert return expression of type 'T.TheEnum.AllCases.Index' to return type 'Int'

Компилируется, когда я использую конкретный тип.

enum MyEnum: CaseIterable {
    case zero
    case one
}

class HasEnumClass {
    typealias E = MyEnum
    var myEnum: MyEnum = .one
}

let h = HasEnumClass()
let caseIndex = type(of: h.myEnum).allCases.firstIndex(of: h.myEnum)
// caseIndex = 1

Ответы [ 2 ]

2 голосов
/ 17 апреля 2019

Тип Index, определенный для Collection, не обязательно должен быть Int, поэтому вы видите ошибку. Вы можете использовать общие ограничения, чтобы требовать этого, хотя:

func getIndexInAllCases<T: HasEnumCase>(theInstance: T) -> Int where T.TheEnum.AllCases.Index == Int {
    // ...
}
0 голосов
/ 17 апреля 2019

Дальтонклейбрук рассуждения и ответ верны: проблема типа Index.

Я обнаружил, что могу также создать массив из результата allCases, а остальное сделает компилятор.

func getIndexInAllCases<T: HasEnumCase>(theInstance: T) -> Int {
    let allCases = Array(type(of: theInstance).TheEnum.allCases)
    let index = allCases.firstIndex(of: theInstance.theCase)!
    return index
}
...