代码之家  ›  专栏  ›  技术社区  ›  Nader

typealias的重新声明无效

  •  0
  • Nader  · 技术社区  · 6 年前

    我有一个通用协议, TwoWayBindDelegate ,它使用泛型关联类型来确定函数的参数。 twoWayBind()

    protocol TwoWayBindDelegate: class {
    
        associatedtype BindType
    
        func twoWayBind(to observable: Observable<BindType>?, observableChanged: ((BindType) -> ())?)
    }
    

    然后我创建了一个类, Reactive<Base: UIView, Type> (符合 双向绑定委托 )你必须用泛型初始化它 Base 。例如: let reactiveSlider = Reacive<UISlider>(slider) .

    我的问题是当我扩展反应性和顺应性时 双向绑定委托 ,我得到一个错误 Invalid redeclaration of 'BindType' 因为我宣布 BindType 双向绑定() 在我的两个分机里。有没有办法让这两个扩展提供不同的实现 双向绑定委托

    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 . 有没有解决办法

    1 回复  |  直到 6 年前
        1
  •  1
  •   matt    6 年前

    我不太明白 typealias 是为了。函数声明本身就足以告诉编译器 BindType 必须是。

    我在你的代码中发现的问题(当然,除了缺少可观察的声明之外)是反应类 它本身 不符合TwowayBindDelegate。为了解决这个问题,我在 twoWayBind 。当我删除了不必要的 类型别名 声明,你为我编译的代码:

    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) -> ())?) {
        }
    }