web-dev-qa-db-ja.com

Swift enum inheritance

Swiftでenumを継承できますか?列挙の継承に関して知っておくべきルールは何ですか?

次のテストコード:

enum TemperatureUnit: Int {
    case Kelvin, Celcius, Farenheit
}

enum TemperatureSubunit : Temperature {  
}

生成する

error: type 'TemperatureSubunit' does not conform to protocol 'RawRepresentable'
50
Boon

Swift言語では、Structs、Enum、およびClassesがあります。StructおよびEnumはコピーで渡されますが、Classesは参照で渡されます。継承のみをクラスでサポートします。

したがって、質問に答えるために、Enum(およびStruct型)を継承することはできません。こちらをご覧ください:

stackOverflowの差分クラスと構造体

64
Korpel

Korpelが既に答えたように、現在、Enumに対してサポートされる実際の継承はありません。そのため、特定のEnumを拡張して別のenumのケースを継承することはできません。

ただし、Enumがプロトコルをサポートし、Swift 2および新しいプロトコル指向プログラミングアプローチ( このビデオ =)、継承に似たものを実装することができます。これは、enumによって駆動される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

    }
}

前のコードは次の表をレンダリングします。

Enum-defined table

プロトコルを実装することで、RegisterTableSection enumがプロトコルで定義されたメソッドと変数に実装を提供する必要があることに注意してください。そして最も興味深いことに、それはinheritsmandatoryTitleプロトコル拡張を介した変数TableSectionのデフォルト実装です。

この例のソースコードをアップロードしました here

56
Luis

私の例を見てください、それははるかに簡単です: enumにSwiftの別のenum値を含めることができますか?

詳細

テスト済み:

  • Xcode 9.2、Swift 4および3
  • Xcode 10.2(10E125)、Swift 5

解決

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)

結果

enter image description hereenter image description here

39