我有一个通用协议TwoWayBindDelegate
,它使用通用关联类型来确定函数twoWayBind()
的参数
protocol TwoWayBindDelegate: class {
associatedtype BindType
func twoWayBind(to observable: Observable<BindType>?, observableChanged: ((BindType) -> ())?)
}
然后我创建了一个类Reactive<Base: UIView, Type>
(符合TwoWayBindDelegate
),您必须使用通用Base
对其进行初始化。例如:let reactiveSlider = Reacive<UISlider>(slider)
。
我的问题是,当我扩展Reactive并符合TwoWayBindDelegate
时,我收到错误Invalid redeclaration of 'BindType'
,因为我在两个扩展程序中都声明了BindType
和twoWayBind()
。有没有办法可以让两个扩展为TwoWayBindDelegate
class Reactive<Base: UIView>: TwoWayBindDelegate {
public var base: Base
init(base: Base) {
self.base = base
}
}
extension Reactive where Base == UISlider {
typealias BindType = Float
func twoWayBind(to observable: Observable<Float>?, observableChanged: ((Float) -> ())?) {
// implement two way bind for UISlider
}
}
extension Reactive where Base == UITextField {
typealias BindType = String
func twoWayBind(to observable: Observable<String>?, observableChanged: ((String) -> ())?) {
// implement two way bind for UITextField
}
}
我做了一些研究,发现它可能是一个错误https://bugs.swift.org/browse/SR-5392。是否碰巧有解决方法
答案 0 :(得分:1)
我不太明白typealias
的用途。单独的函数声明足以告诉编译器BindType
必须是什么。
我在代码中发现的问题(当然除了缺少的Observable声明)是Reactive类本身不符合TwoWayBindDelegate。为了解决这个问题,我投入了twoWayBind
的任意实现。当我这样做,当我删除不必要的typealias
声明时,你的代码为我编译:
struct Observable<T> {}
protocol TwoWayBindDelegate: class {
associatedtype BindType
func twoWayBind(to observable: Observable<BindType>?, observableChanged: ((BindType) -> ())?)
}
class Reactive<Base: UIView>: TwoWayBindDelegate {
public var base: Base
init(base: Base) {
self.base = base
}
func twoWayBind(to observable: Observable<Int>?, observableChanged: ((Int) -> ())?) {
}
}
extension Reactive where Base == UISlider {
func twoWayBind(to observable: Observable<Float>?, observableChanged: ((Float) -> ())?) {
}
}
extension Reactive where Base == UITextField {
func twoWayBind(to observable: Observable<String>?, observableChanged: ((String) -> ())?) {
}
}