Pouvez-vous hériter de l'énum en Swift? Quelles sont les règles à connaître concernant l'héritage enum?
Le code de test suivant:
enum TemperatureUnit: Int {
case Kelvin, Celcius, Farenheit
}
enum TemperatureSubunit : Temperature {
}
génère
error: type 'TemperatureSubunit' does not conform to protocol 'RawRepresentable'
Dans la langue Swift, nous avons Structs, Enum et Classes. Struct et Enum sont passées par copie, mais les classes sont passées par référence. Seules les classes prennent en charge l'héritage, contrairement à Enum et Struct.
Donc, pour répondre à votre question, vous ne pouvez pas avoir d'héritage avec Enum (et les types Struct). Regardez ici:
Comme Korpel a déjà répondu, à l'heure actuelle, aucun héritage n'est pris en charge pour Enums. Il n'est donc pas possible qu'un certain Enum étende et hérite des cas d'un autre enum.
Cependant, j’ajouterais pour terminer que Enums prend en charge les protocoles et, avec les extensions de protocole introduites dans Swift 2 et la nouvelle approche de programmation orientée protocole (voir cette vidéo =), il est possible d’implémenter quelque chose qui ressemble à l’héritage. C’est une technique que j’utilise beaucoup pour définir UITableViewController
: s pilotée par des énumérations, pour spécifier les sections de la table et les lignes de chaque section, et pour ajouter un comportement utile, voir par exemple l'exemple de code suivant:
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
}
}
Le code précédent rendrait le tableau suivant:
Notez qu'en implémentant le protocole, notre RegisterTableSection
enum doit fournir des implémentations aux méthodes et aux variables définies dans le protocole. Et le plus intéressant, il hérite d'une implémentation par défaut de la variable mandatoryTitle
à travers l'extension de protocole TableSection
J'ai téléchargé le code source de cet exemple ici
Regardez mon exemple, il est beaucoup plus facile: ne énumération peut-elle contenir une autre valeur d’énum dans Swift?
Testé sur:
enum State {
case started
case succeeded
case failed
}
enum ActionState {
case state(value: State)
case cancelled
}
ActionState enum a 4 valeurs:
.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)