我有一个类,名为
我需要以某种方式将
StateMachine
,它是通用的,可以实现不同的状态集作为枚举。我想使用一个StateMachineDelegate
协议来通知代理当状态机进入一个新状态时。
但这不能工作,因为代理协议也是带有类型要求的泛型。错误显示在声明delegate
属性的位置。protocol StateType: Hashable {}
protocol StateMachineDelegate: class {
typealias S: StateType
func stateMachine(stateMachine: StateMachine<S>, didEnterState newState: S)
}
class StateMachine<S: StateType> {
typealias State = S
weak var delegate: StateMachineDelegate?
//~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
//Protocol 'StateMachineDelegate' can only be used as a generic constraint because it has Self or associated type requirements
var currentState: State {...}
init(initialState: State) {...}
func applyState(toState: State) -> Bool {
...
currentState = toState
delegate?.stateMachine(self, didEnterState: toState)
...
}
}
我需要以某种方式将
StateMachineDelegate.S == S
与StateMachine
类关联起来,但我不确定如何做到这一点,或者是否可能。我尝试过:class StateMachine<S: StateType, D: StateMachineDelegate where D.S == S> {
...
weak var delegate: D?
...
}
但是我在重构协议以正确声明StateMachine的泛型类型时遇到了困难。在创建一个StateMachine时,事先声明委托类型似乎并不合适。
StateMachineDelegate
的类型要求得到满足,因为StateMachine
在这方面没有做出任何承诺。如果StateMachine
包括一个泛型类型参数,限制为StateMachineDelegate
,那么它承诺在运行时将被替换为一个令人满意的类(但然后我会在委托协议中得到一个奇怪的StateMachine<S,D>
参数)。也许随着语言的发展,这将成为可能。 - StuartHashable
也不应该成为问题。 - Stuarttypealias StateMachine: Stateful
,然后protocol Stateful { typealias State }
和class StateMachine<S: StateType>: Stateful {...}
... 然后在委托中可以引用StateMachine.State
)。但是委托协议仍将是通用的(具有相关类型要求),因此无法解决问题。 - Stuart