использование enum для хранения текущего класса состояний в swift - PullRequest
1 голос
/ 13 марта 2019

У меня есть два класса:

class State1 {
    static func getInfo() -> String {
        return "sometext1"
    }
}

class State2 {
    static func getInfo() -> String {
        return "sometext2"
    }
}

У меня также есть это перечисление для состояний:

enum State {
    case state1
    case state2

    var instance: Any {
        switch self {
        case .state1:
            return State1.self
        case .state2:
            return State2.self
        }
    }
}

И я пытаюсь сохранить текущее состояние в переменной и вызвать метод класса на основе перечисления:

var currentState = State.state1.instance
print(currentState) //prints State1

currentState.getInfo() //currentState is of type Any so not possible to call State1 methods

Есть идеи, как обойти это?

Ответы [ 2 ]

3 голосов
/ 13 марта 2019

Чтобы ответить на ваш основной вопрос, вы можете использовать перечисления со связанными значениями для лучшей обработки регистра.

Связанные значения

...

Вы можете определить перечисления Swift для хранения связанных значений любого данного типа, и типы значений могут быть разными для каждого случая перечисления, если это необходимо.Перечисления, подобные этим, известны как различимые объединения, помеченные объединения или варианты в других языках программирования.

Ссылка: Быстрая документация по перечислениям


Пример:

enum State {
    case state1(_ state: State1.Type)
    case state2(_ state: State2.Type)
}

let currentState = State.state1(State1.self)

//Using switch for handling multiple cases
switch currentState {
case .state1(let state):
    state.getInfo()
case .state2(let state):
    state.getInfo()
}

//Using if for handling single cases 
if case State.state1(let state) = currentState {
    state.getInfo()
}

Подробнее о перечислениях со связанными значениями здесь:

2 голосов
/ 13 марта 2019

Если классы мало что делают, я бы просто поместил функции-члены в перечисление

enum State{
    case state1
    case state2

    func getInfo() -> String
    {
        switch self
        {
        case .state1:
            return "sometext1"
        case .state2:
            return "sometext2"
        }
    }
}


var currentState = State.state1
print(currentState)
print(currentState.getInfo())

Если вы действительно хотите, чтобы государства имели свой собственный класс, вы должны объявить, что они расширяют один и тот же суперкласс или реализуют тот же протокол, и использовать этот суперкласс / протокол в перечислении.

protocol StateProtocol
{
    static func getInfo() -> String
}

class State1 : StateProtocol
{
    static func getInfo() -> String {
        return "sometext1"
    }
}

class State2 : StateProtocol
{
    static func getInfo() -> String {
        return "sometext2"
    }
}

enum State {

    case state1
    case state2

    var instance: StateProtocol.Type {
        switch self {
        case .state1:
            return State1.self
        case .state2:
            return State2.self
        }
    }
}

var currentState = State.state1.instance
print(currentState) //prints State1
print(currentState.getInfo())

Хотя мне не совсем удобно возвращать Type класса только для того, чтобы использовать его статический метод.

Гораздо логичнее использовать класс State в качестве экземпляров, а не просто использовать его статический метод. (Почему вы называете экземпляр переменной, пока он не является экземпляром?)

class StateClass
{
    func getInfo() -> String
    {
        return "default text"
    }

}

class State1 : StateClass
{
    override func getInfo() -> String
    {
        return "sometext1"
    }

    static let instance = State1()
}

class State2 : StateClass
{
    override func getInfo() -> String
    {
        return "sometext2"
    }

    static let instance = State2()
}

enum State{
    case state1
    case state2

    var instance : StateClass
    {
        switch self{
        case .state1:
            return State1.instance
        case .state2:
            return State2.instance
        }
    }
}

var currentState = State.state1.instance
print(currentState)
print(currentState.getInfo())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...