我曾多次在Swift中使用类型擦除,但通常都涉及到通用协议。但在这种情况下,不仅涉及一个通用枚举,还涉及到通用协议,让我很困惑。
以下是我的通用枚举和通用协议以及必要的扩展:
enum UIState<T> {
case Loading
case Success([T])
case Failure(ErrorType)
}
protocol ModelsDelegate: class {
associatedtype Model
var state: UIState<[Model]> { get set }
}
extension ModelsDelegate {
func getNewState(state: UIState<[Model]>) -> UIState<[Model]> {
return state
}
func setNewState(models: UIState<[Model]>) {
state = models
}
}
这是我的类型擦除通用类:
class AnyModelsDelegate<T>: ModelsDelegate {
var state: UIState<[T]> {
get { return _getNewState(UIState<[T]>) } // Error #1
set { _setNewState(newValue) }
}
private let _getNewState: ((UIState<[T]>) -> UIState<[T]>)
private let _setNewState: (UIState<[T]> -> Void)
required init<U: ModelsDelegate where U.Model == T>(_ models: U) {
_getNewState = models.getNewState
_setNewState = models.setNewState
}
}
我遇到了以下错误(它们在代码样本中被标记出来):
错误 #1:
无法将类型为 '(UIState<[T]>).Type'(即 'UIState<Array<T>>.Type')的值转换为预期的参数类型 'UIState<[_]>'(即 'UIState<Array<_>>')
我已经花了一段时间在这个问题上,并且已经有很多关于这段代码的变化“几乎可以工作”。这个错误总是与getter有关。
getNewState
函数需要一个输入参数,它应该是一个() -> UIState <[Model]>
吧?虽然如果你的getNewState
和setNewState
函数仅仅是存在于你的类型擦除中以便转发获取和设置,那么它们并不是必要的,因为你可以使用闭包直接在类型擦除中完成这些操作(即_getNewState = { models.state }
和_setNewState = { models.state = $0 }
)。 - Hamish