Swift 4.2 представляет новый протокол CaseIterable
, который автоматически генерирует свойство массива всех дел в перечислении.
Теперь я хочу реализовать метод по умолчанию для наследования Enum от CaseIterable
, который может возвращать следующий случай конкретного случая. Если этот случай - последний случай, верните первый случай. Как круг.
Если я напишу это для конкретного Enum, он будет работать правильно:
enum Direction: CaseIterable {
case east, south, west, north
func next() -> Direction {
let all = type(of: self).allCases // 1
if self == all.last! {
return all.first!
} else {
let index = all.firstIndex(of: self)!
return all[index + 1]
}
}
}
print(Direction.east.next()) // south
print(Direction.north.next()) // east
Но я хочу реализовать эту функцию для многих Enum. Повторное копирование и вставка кода не годятся (не говоря уже о том, что этот код абсолютно одинаков для каждого Enum).
Я попробовал это. Но что-то пошло не так.
(Я предлагаю вам скопировать следующий код на игровую площадку, чтобы вы могли быстрее понять эту проблему):
extension CaseIterable {
func next() -> Self {
let all = type(of: self).allCases // 1
if self == all.last { // 2
return all.first!
} else {
let index = all.firstIndex { (ele) -> Bool in
self == ele // 3
}
return all[index + 1]
}
}
}
Три очка:
all
- Self.AllCases
, тип Collection
. Но в приведенном выше методе это [Direction]
.
- Ошибка в строке 2 говорит
Value of type 'Self.AllCases' has no member 'last'
(Даже если я не использую last
, ошибки в строке 3 нельзя избежать.)
- В строке 3 ошибка
Binary operator '==' cannot be applied to two 'Self' operands
И даже я использую общие ограничения, это то же самое.
func next<T: CaseIterable>(element: T) -> T {...}
Есть какие-нибудь решения? :)