问题描述
我有一个通用协议 TwoWayBindDelegate
,该协议使用通用关联类型来确定函数 twoWayBind()
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) -> ())?)
}
然后我创建了一个类, Reactive< Base:UIView,Type>
(符合 TwoWayBindDelegate
),在其中必须使用通用的 Base对其进行初始化.
.例如: let reactSlider = Reacive< UISlider>(滑块)
.
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)
.
我的问题是,当我扩展Reactive并符合 TwoWayBindDelegate
时,出现错误 BindType'无效重新声明
,因为我声明了 BindType 我的两个扩展中的code>和
twoWayBind()
.有没有办法让两个扩展都为 TwoWayBindDelegate
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
}
}
我做了一些研究,发现它可能是一个错误 https://bugs.swift.org/browse/SR-5392 .碰巧有解决方法
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
推荐答案
我不太明白 typealias
的用途.仅函数声明就足以告诉编译器 BindType
必须是什么.
I don't quite see what the typealias
is for. The function declaration alone is sufficient to tell the compiler what BindType
must be.
我在您的代码中发现的问题(当然,除了缺少的Observable声明)是Reactive类 itself 不符合TwoWayBindDelegate.为了解决这个问题,我引入了 twoWayBind
的任意实现.当我这样做时,以及当我删除了不必要的 typealias
声明时,您的代码就会为我编译:
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) -> ())?) {
}
}
这篇关于无效的typealias声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!