如何返回和使用 Swift 类类型或方法的枚举

Ken*_*ner 2 enums swift swift-protocols

我正在构建一个简单的状态引擎,我想要一个可以在其中移动的状态集合。

我想要解决这个问题的方法是枚举可能的状态,这些状态也定义了表示该状态的相应类,这样如果我决定转移到该状态,我就可以动态地构造该状态。

在下面的代码中,我尝试构建一个运行良好的 State 对象的枚举。我遇到困难的是,如何访问此枚举的值作为我可以从中调用静态构造函数方法的类型?在下面的代码中,我得到的错误是尝试使用枚举值调用 moveToState 并不代表 StartupStates 类型,这似乎......

所以问题确实是,为什么这不起作用,或者我可以通过什么其他方式拥有类类型和/或类级别(静态)方法的枚举来调用构造函数?

public enum StartupStates<State> {
case Start(StartState)
case DownloadFiles(DownloadFilesState)
 }

 public protocol State {
   var stateEngine : StateEngine {get set}
 }

public class StateEngine
{
    var currentState : State?
    public func moveToState(newState : StartupStates<State>)
    {
    }
}

public class StartState : BaseState
{
    func doStateTasks()
    {
        // Move to next state, downloading files
        // ERROR IS HERE: 
        // "Cannot convert file of type '(DownloadFileState)->StartupStates<...>' to expected argument type 'StartupStates<State>'"

        stateEngine.moveToState(StartupStates.DownloadFiles)
    }
}

public class DownloadFilesState : BaseState
{
}


public class BaseState : State {
    public var stateEngine : StateEngine

    required public init( stateEngine : StateEngine ) {
        self.stateEngine = stateEngine
    }

    public static func stateCreator(stateEngine : StateEngine) -> Self {
        return self.init( stateEngine: stateEngine )
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*nzo 5

字符串解决方案:

在这种情况下,您也许可以发挥NSClassFromString自己的优势。考虑以下示例:

enum State: String {
    case StartState = "StartClass"
    case DownloadState = "DownloadClass"
    case BaseState = "BaseClass"

    var klass: AnyClass {
        return NSClassFromString(self.rawValue)!
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您正在寻找这种解决方案,请告诉我。

替代解决方案:

如果您不想依赖于键入字符串解决方案,那么您需要为类类型提供一个简单的 switch 语句:

class StartClass {}
class DownloadClass {}
class BaseClass {}

enum State {
    case StartState
    case DownloadState
    case BaseState

    var klass: AnyClass {
        switch self {
        case .StartState:
            return StartClass.self
        case .DownloadState:
            return DownloadClass.self
        case .BaseState:
            return BaseClass.self
        }
    }
}
Run Code Online (Sandbox Code Playgroud)