用于泛型类的Swift委托协议 [英] Swift delegate protocol for generic class
问题描述
我有一个类, StateMachine
,这是通用的,允许将不同的状态集合实现为例如枚举。我想使用 StateMachineDelegate
协议通知代理机构状态机进入新的状态。
I have a class, StateMachine
, that is generic to allow for different sets of states to be implemented as, for example, an enum. I want to use a StateMachineDelegate
protocol to notify a delegate when the state machine enters a new state.
但是因为委托协议也是类型要求通用的,所以不起作用。错误显示在哪里声明委托
属性。
But this doesn't work since the delegate protocol is also generic with type requirements. The error shows where the delegate
property is declared.
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
类,但我不知道如何做到这一点,或者如果可能的话。我试过:
I need to somehow associate that StateMachineDelegate.S == S
in the StateMachine
class, but I'm not sure how to do this, or if it's possible. I tried:
class StateMachine<S: StateType, D: StateMachineDelegate where D.S == S> {
...
weak var delegate: D?
...
}
但是我试图重做协议正确声明通用类型 StateMachine
。而在创建一个 StateMachine
时,就不得不先声明该委托的类型。
but then I get stuck trying to rework the protocol to properly declare the generic type of StateMachine
. And it doesn't seem right to have to declare the type of the delegate up front when creating a StateMachine
.
推荐答案
看看这个解决方法是否符合您的需求,它使用 @autoclosure
来摆脱递归泛型定义的问题: / p>
See if this workaround is ok for your needs, it uses @autoclosure
to get rid of a problem with recursive generic definitions:
class StateMachine<S: Printable, D: StateMachineDelegate where S == D.StateType> {
var currentState: S {
didSet {
// The observer
if let delegate = self.delegate {
delegate.stateMachine(self, didEnterState: self.currentState)
}
}
}
var delegate: D?
init(initialState: S) {
self.currentState = initialState
}
}
protocol StateMachineDelegate: class {
typealias StateType: Printable
// Workaround with autoclosure
func stateMachine(machine: @autoclosure() -> StateMachine<StateType, Self>, didEnterState newState: StateType)
}
final class ADelegate: StateMachineDelegate {
typealias StateType = Int
func stateMachine(machine: @autoclosure () -> StateMachine<StateType, ADelegate>, didEnterState newState: StateType) {
// Need to _unbox_ the sander from the closure
let sender = machine()
println(newState)
println("State from sender: \(sender.currentState)")
}
}
let stateMachine = StateMachine<Int, ADelegate>(initialState: 24)
stateMachine.delegate = ADelegate()
stateMachine.currentState = 50
顺便说一下,如果你得到砂光机,可能你不需要得到 newState
。
我使用可打印
代替 Hashable
作为示例。
By the way, consider that if you get the sander, probably you don't need to get the newState
passed.
I used Printable
in place of Hashable
for the example.
这篇关于用于泛型类的Swift委托协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!