web-dev-qa-db-fra.com

Swift enum héritage

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'
50
Boon

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:

classes de différences stackOverflow vs structs

64
Korpel

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:

Enum-defined table

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

56
Luis

Regardez mon exemple, il est beaucoup plus facile: ne énumération peut-elle contenir une autre valeur d’énum dans Swift?

Détails

Testé sur:

  • Xcode 9.2, Swift 4 et 3
  • Xcode 10.2 (10E125), Swift 5

Solution

enum State {
    case started
    case succeeded
    case failed
}

enum ActionState {
    case state(value: State)
    case cancelled
}

Résultat

ActionState enum a 4 valeurs:

.state(value: .started)
.state(value: .succeeded)
.state(value: .failed)
.cancelled

Un autre échantillon

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)

Résultat

enter image description hereenter image description here

39
Vasily Bodnarchuk