Может ли перечисление содержать другие значения перечисления в Swift?
Я хотел бы поделиться некоторыми свойствами перечисления. Что-то вроде:
enum State {
case started
case succeeded
case failed
}
enum ActionState {
include State // what could that be?
case cancelled
}
class Action {
var state: ActionState = .started
func set(state: State) {
self.state = state
}
func cancel() {
self.state = .cancelled
}
}
Я понимаю почему ActionState
не может наследовать от State
(потому что государство cancelled
не имеет представительства в State
) но я все еще хочу сказать: "ActionState похож на State с большим количеством опций, и ActionState может получать входные данные, имеющие тип State, поскольку они также имеют тип ActionState"
Я вижу, как я мог заставить вышеупомянутую логику работать с копированием случаев в ActionState
и имея переключатель в set
функция. Но я ищу лучший путь.
Я знаю, что enum не может наследоваться в Swift, и я прочитал ответ протокола swift-enum-наследования. Он не учитывает необходимость "наследования" или включения дел из другого перечисления, а только свойства и переменные.
3 ответа
Фиксированный код
import Foundation
enum State {
case started
case succeeded
case failed
}
enum ActionState {
case state(value: State)
case cancelled
}
class Action {
var state: ActionState = .state(value: .started)
func set(state: State) {
self.state = .state(value: state)
}
func cancel() {
self.state = .cancelled
}
var description:String {
var result = "Action "
switch state {
case .state(value: .started):
result += "\(state)"
case .state(value: _):
result += "\(state)"
case .cancelled:
result += "cancelled"
}
return result
}
}
let obj = Action()
print(obj.description)
obj.set(state: .failed)
print(obj.description)
obj.set(state: .succeeded)
print(obj.description)
obj.cancel()
print(obj.description)
Результат
Мне пришлось проверить документ лицензии пользователя. У которого было две стороны - передняя и задняя. В зависимости от документа проверки может быть действительным или недействительным. Кроме того, UX был таким, что отображалось активное или неактивное состояние с соответствующими цветами. В итоге я сделал следующее перечисление.
public enum Validity {
case pending(_ selectState: SelectState)
case valid(_ selectState: SelectState)
case invalid(_ selectState: SelectState)
enum SelectState {
case active(_ side: Side)
case inactive(_ side: Side)
enum Side {
case front
case back
}
}
}
Что можно назвать -
public var validity: Validity = Validity.pending(.active(.front))
Хотел бы я быть более чистым, как...
Validity.pending.active.front
но это пока решение для Enum внутри другого enum может быть.
Swift 5.1, Xcode 11.4.1
Даже если невозможно напрямую расширить перечисление, как описано в других ответах, вы можете обойти это, используя необработанные значения. Например:
enum State: Int {
case started
case succeeded
case failed
}
enum ActionState: Int {
case started
case succeeded
case failed
case cancelled
}
class Action {
var state: ActionState = .started
func set(state: State) {
self.state = ActionState(rawValue: state.rawValue)!
}
func cancel() {
self.state = .cancelled
}
}
Я думаю, что это самое чистое решение, хотя оно требует некоторого дублирования кода при определении перечисления. Крайне важно убедиться, что необработанные значения междуState
иActionState
соответствовать.