我正在做这样的事情:
protocol StateType { }
struct DogState: StateType { }
struct CatState: StateType { }
protocol Action {
associatedType ST
func process() -> ST
}
struct DogAction {
func process() -> DogState { return DogState() }
}
struct CatAction {
func process() -> CatState { return CatState() }
}
let actions = [DogAction(), CatAction()]
actions.forEach {
$0.process()
}
我曾尝试用类型擦除来摆弄,但是我无法解决无法创建异构数组的问题。
struct AnyActionProtocol<A: Action, ST: StateType>: Action where A.StateType == ST {
let action: A
init(_ action: A) {
self.action = action
}
func process() -> ST {
return action.process()
}
}
let dap = AnyActionProtocol<DogAction, DogState>(DogAction())
let cap = AnyActionProtocol<CatAction, CatState>(CatAction())
当我尝试此操作时,我得到的错误是异构集合常量只能推断为[Any],这是我要避免的事情。
任何帮助将不胜感激!
答案 0 :(得分:0)
PAT通常很复杂,并且不涉及更简单的解决方案。我建议您针对您的问题提出一些更简单的设计。您的方法的问题实际上是具有PAT和嵌套协议,并试图使它们协同工作。
即使您将擦除Action
键入类似AnyAction
的某种类型,这两种不同的类型DogAction
和CatAction
也会再次产生不同的类型,并且您不能在数组内将它们混合在一起。您可能要做的是进行两种类型的擦除,一种用于Action
,另一种用于StateType
。当您将CatAction
或DogAction
包装在AnyAction
内时,它们都将以类型擦除状态包装到AnyState
。
这里是一个示例,您可以使用这种类型来擦除两种协议,
protocol StateType { }
struct DogState: StateType { }
struct CatState: StateType { }
protocol Action {
associatedtype ST: StateType
func process() -> ST
}
struct DogAction: Action {
func process() -> DogState { return DogState() }
}
struct CatAction: Action {
func process() -> CatState { return CatState() }
}
struct AnyState: StateType {
let state: StateType
init(_ state: StateType) {
self.state = state
}
}
struct AnyAction: Action {
typealias ST = AnyState
let processor: () -> AnyState
init<T: Action>(_ a: T) {
self.processor = {
return AnyState(a.process())
}
}
func process() -> AnyState {
return processor()
}
}
let cat = AnyAction(CatAction())
let dog = AnyAction(DogAction())
let actions = [cat, dog]
actions.forEach { action in
action.process()
}
我仍然认为您应该重新考虑解决方案,随着类型的增加,这可能会变得更加复杂。