Быстрое перечисление наследования
Можете ли вы наследовать enum в Swift? Какие правила следует знать в отношении наследования перечисления?
Следующий тестовый код:
enum TemperatureUnit: Int {
case Kelvin, Celcius, Farenheit
}
enum TemperatureSubunit : Temperature {
}
генерирует
error: type 'TemperatureSubunit' does not conform to protocol 'RawRepresentable'
3 ответа
В быстром языке у нас есть Structs,Enum и Classes.Struct и Enum передаются посредством копирования, но классы передаются по ссылке. Только классы поддерживают наследование, Enum и Struct - нет. Так что, чтобы ответить на ваш вопрос, вы не можете получить наследование с Enum (и типы структур). Посмотрите здесь
Как уже ответил Korpel, в настоящее время для Enums не поддерживается фактическое наследование. Поэтому невозможно, чтобы определенный Enum расширял и наследовал случаи другого Enum.
Однако для завершения я бы добавил, что Enums поддерживает протоколы, и вместе с расширениями протоколов, представленными в Swift 2, и новым подходом к программированию на основе протоколов (см. Это видео), возможно реализовать нечто, напоминающее наследование. Эту технику я часто использую для определения UITableViewController
: s управляется перечислениями, чтобы указать разделы таблицы и строки в каждом разделе, и добавить некоторое полезное поведение. Смотрите, например, следующий пример кода:
import UIKit
protocol TableSection {
static var rows: [Self] { get }
var title: String { get }
var mandatoryField: Bool { get }
}
extension TableSection {
var mandatoryTitle: String {
if mandatoryField {
return "\(title)*"
} else {
return title
}
}
}
enum RegisterTableSection: Int, TableSection {
case Username
case Birthdate
case Password
case RepeatPassword
static var rows: [RegisterTableSection] {
return [.Username, .Password, .RepeatPassword]
}
var title: String {
switch self {
case .Username:
return "Username"
case .Birthdate:
return "Date of birth"
case .Password:
return "Password"
case .RepeatPassword:
return "Repeat password"
}
}
var mandatoryField: Bool {
switch self {
case .Username:
return true
case .Birthdate:
return false
case .Password:
return true
case .RepeatPassword:
return true
}
}
}
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return RegisterTableSection.rows.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
guard let row = RegisterTableSection(rawValue: indexPath.row) else {
// This should never happen
return UITableViewCell()
}
let cell = UITableViewCell()
cell.textLabel?.text = row.mandatoryTitle
return cell
}
}
Предыдущий код будет отображать следующую таблицу:
Обратите внимание, как при реализации протокола наши RegisterTableSection
enum должен предоставлять реализации методов и переменных, определенных в протоколе. И что самое интересное, он наследует реализацию переменной по умолчанию mandatoryTitle
сквозь TableSection
расширение протокола
Я загрузил исходный код этого примера здесь
Посмотрите на мой пример, это намного проще: может ли перечисление содержать другие значения перечисления в Swift?
идея
enum State {
case started
case succeeded
case failed
}
enum ActionState {
case state(value: State)
case cancelled
}
Результат
Экземпляр ActionState теперь имеет 4 значения:
.state(value: .started)
.state(value: .succeeded)
.state(value: .failed)
.cancelled
Еще один образец
import Foundation
enum StringCharactersTransformType {
case upperCase
case lowerCase
}
enum StringTransformType {
case state(value: StringCharactersTransformType)
case normal
static var upperCase: StringTransformType {
return .state(value: .upperCase)
}
static var lowerCase: StringTransformType {
return .state(value: .lowerCase)
}
}
var type = StringTransformType.normal
print(type)
type = .upperCase
print(type)
type = .lowerCase
print(type)