ios Swift 枚举继承

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33191532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:02:35  来源:igfitidea点击:

Swift enum inheritance

iosswiftinheritanceenumsrawrepresentable

提问by Boon

Can you inherit enum in Swift? What are the rules that one should be aware of with regards to enum inheritance?

你能在 Swift 中继承 enum 吗?关于枚举继承,应该注意哪些规则?

The following test code:

以下测试代码:

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

enum TemperatureSubunit : Temperature {  
}

generates

产生

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

回答by Korpel

In Swift language, we have Structs, Enum and Classes. Struct and Enum are passed by copy but Classes are passed by reference. Only Classes support inheritance, Enum and Struct don't.

在 Swift 语言中,我们有结构、枚举和类。Struct 和 Enum 是通过副本传递的,而类是通过引用传递的。只有类支持继承,枚举和结构不支持。

So to answer your question, you can't have inheritance with Enum (and Struct types). Have a look here:

所以要回答你的问题,你不能继承 Enum (和 Struct 类型)。看看这里:

stackOverflow difference classes vs structs

stackOverflow 差异类与结构

回答by Luis

As Korpel answered already, currently there is no actual inheritance supported for Enums. So it is not possible to have a certain Enum extend and inherit the cases of another enum.

正如 Korpel 已经回答的那样,目前枚举不支持实际继承。所以不可能让某个 Enum 扩展并继承另一个 enum 的案例。

However, I would add for completion, that Enums do support protocols, and together with protocol extensions introduced in Swift 2 and the new protocol-oriented programming approach (see this video), it is possible to implement something that resembles inheritance. This is a technique I use a lot to define UITableViewController:s driven by enums, to specify the sections of the table, and the rows within each section, and to add some useful behaviour. See for example the following sample code:

但是,我想补充一点,Enum 确实支持协议,并且与 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

    }
}

The previous code would render the following table:

前面的代码将呈现下表:

Enum-defined table

枚举定义的表

Notice how by implementing the protocol, our RegisterTableSectionenum has to provide implementations to methods and variables defined in the protocol. And most interestingly, it inheritsa default implementation of the variable mandatoryTitlethrough the TableSectionprotocol extension

注意通过实现协议,我们的RegisterTableSection枚举必须为协议中定义的方法和变量提供实现。最有趣的是,它通过协议扩展继承了变量的默认实现mandatoryTitleTableSection

I have uploaded the source code of this example here

我已经在这里上传了这个例子的源代码

回答by Vasily Bodnarchuk

Look at my example, it is much easier: Can an enum contain another enum values in Swift?

看看我的例子,它更容易:在 Swift 中,一个枚举可以包含另一个枚举值吗?

Details

细节

Tested on:

测试:

  • Xcode 9.2, Swift 4 and 3
  • Xcode 10.2 (10E125) and 11.0 (11A420a), Swift 5
  • Xcode 9.2、Swift 4 和 3
  • Xcode 10.2 (10E125) 和 11.0 (11A420a),Swift 5

Solution

解决方案

enum State {
    case started
    case succeeded
    case failed
}

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

Result

结果

ActionState enum has 4 values:

ActionState 枚举有 4 个值:

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


Another sample

另一个样本

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)

Result

结果

enter image description hereenter image description here

在此处输入图片说明在此处输入图片说明