Reputation: 1148
I have a generic protocol, TwoWayBindDelegate
, that uses the generic associated type to determine the parameters of the function twoWayBind()
protocol TwoWayBindDelegate: class {
associatedtype BindType
func twoWayBind(to observable: Observable<BindType>?, observableChanged: ((BindType) -> ())?)
}
I then created a class, Reactive<Base: UIView, Type>
(which conforms to TwoWayBindDelegate
) where you have to initialize it with the generic Base
. For eg: let reactiveSlider = Reacive<UISlider>(slider)
.
My issue is when I am extending Reactive and conforming to TwoWayBindDelegate
, I get an error Invalid redeclaration of 'BindType'
because I am declaring BindType
and twoWayBind()
in both my extensions. Is there a way I can have both extensions provide different implementations for 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
}
}
I did some research and found out that it may be a bug https://bugs.swift.org/browse/SR-5392. Does there happen to be a workaround
Upvotes: 1
Views: 755
Reputation: 535557
I don't quite see what the typealias
is for. The function declaration alone is sufficient to tell the compiler what BindType
must be.
The problem I found with your code (apart from the missing Observable declaration, of course) is that the Reactive class itself doesn't conform to TwoWayBindDelegate. To get around that, I threw in an arbitrary implementation of twoWayBind
. When I did, and when I deleted the unnecessary typealias
declarations, your code compiled for me:
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) -> ())?) {
}
}
Upvotes: 2