Быстрое перечисление наследования

Можете ли вы наследовать 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 (и типы структур). Посмотрите здесь

классы различий stackOverflow против структур

Как уже ответил 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)

Результат

введите описание изображения здесь введите описание изображения здесь

Другие вопросы по тегам