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

时间:2023-01-26 15:11:47

I'm building a simple state engine, where I want a collection of states that I can move between.

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

The way I'd like to go about this is to have an enumeration of states that are possible that also define the corresponding class that represents that state, so that I can construct the state dynamically if I decide to move to that state.

我想要这样做的方法是有一个可能的状态枚举,也可以定义代表该状态的相应类,这样如果我决定移动到那个状态,我就可以动态构造状态。

In the code below I've tried building an enum of State objects which works fine. Where I get stuck is, how can I access the values of this enum as types that I can call a static constructor method from? In the code below the error I get is that the attempt to call moveToState with an enum value does not represent the StartupStates type, which it seems to...

在下面的代码中,我尝试构建一个状态对象的枚举,它工作正常。我遇到的问题是,我如何访问此枚举的值作为我可以从中调用静态构造函数方法的类型?在下面的代码中我得到的错误是,使用枚举值调用moveToState的尝试不代表StartupStates类型,它似乎......

So the question is really, why does this not work, or what other way can I have an enum of class types and/or class level (static) methods to call a constructor from?

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

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 )
    }
}

2 个解决方案

#1


1  

String Solution:

You may be able to use NSClassFromString to your advantage in this scenario. Consider the following example:

在这种情况下,您可以使用NSClassFromString。请考虑以下示例:

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

    var klass: AnyClass {
        return NSClassFromString(self.rawValue)!
    }
}

Let me know if this sort of solution is what you are looking for.

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

Alternative Solution:

If you want to not depend on typing the string solutions then you'll need to have a simple switch statement for the class types:

如果您不想依赖于键入字符串解决方案,那么您需要为类类型设置一个简单的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
        }
    }
}

#2


0  

How about this:

这个怎么样:

class StartState : BaseState {
    func doStateTasks() {        
        let download = DownloadFilesState(stateEngine: StateEngine())
        stateEngine.moveToState(.DownloadFiles(download))
   }
}

Because DownloadFiles enum need a DownloadFilesState object as define in enum.

因为DownloadFiles枚举需要在枚举中定义一个DownloadFilesState对象。

#1


1  

String Solution:

You may be able to use NSClassFromString to your advantage in this scenario. Consider the following example:

在这种情况下,您可以使用NSClassFromString。请考虑以下示例:

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

    var klass: AnyClass {
        return NSClassFromString(self.rawValue)!
    }
}

Let me know if this sort of solution is what you are looking for.

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

Alternative Solution:

If you want to not depend on typing the string solutions then you'll need to have a simple switch statement for the class types:

如果您不想依赖于键入字符串解决方案,那么您需要为类类型设置一个简单的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
        }
    }
}

#2


0  

How about this:

这个怎么样:

class StartState : BaseState {
    func doStateTasks() {        
        let download = DownloadFilesState(stateEngine: StateEngine())
        stateEngine.moveToState(.DownloadFiles(download))
   }
}

Because DownloadFiles enum need a DownloadFilesState object as define in enum.

因为DownloadFiles枚举需要在枚举中定义一个DownloadFilesState对象。