我不得不在Swift中使用类型擦除几次,但它总是涉及一个通用协议。在这种情况下,它涉及到泛型枚举和和泛型协议,我很难过。使用通用枚举和通用协议的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:
Cannot convert value of type '(UIState<[T]>).Type' (aka 'UIState<Array<T>>.Type') to expected argument type 'UIState<[_]>' (aka 'UIState<Array<_>>')
我一直在研究这一段时间,并且在这段代码中已经有了几乎所有的“几乎可行”的变体。该错误总是与吸气剂有关。
你传递一个类型,即采用的是 – dan
I型的实例的方法'有点困惑为什么你的'getNewState'函数需要一个输入,当然它应该是一个'() - > UIState <[Model]>'?虽然如果你的'getNewState'和'setNewState'函数只是为了将获取和设置转发到你的类型擦除,它们是没有必要的,因为你可以直接在类型擦除中使用闭包(即'_getNewState = {models。状态}'&'_setNewState = {models.state = $ 0}')。 – Hamish
是的,我也有点困惑:)。它需要一个输入,因为最初我在没有输入时收到错误。让我尝试重构。 – damianesteban