【问题标题】:Protocol Conformance Check协议一致性检查
【发布时间】:2019-12-31 17:13:51
【问题描述】:

如何使用 AssociatedType 对协议执行一致性检查。 Xcode 显示错误:

Protocol 'MyListener' 只能用作通用约束,因为 它有 Self 或关联的类型要求

我的最终目标是从weakObjects 数组中提取“MyListener.section”,其中处理程序与函数参数匹配。

注意。 weakObjects 的 NSPointerArray 是假设捕获不同类型的 MyListeners。

public class MyHandler<O,E> {
    var source = [O]()
    var dest = [E]()
}
public protocol MyListener:class {
    var section: Int {get}
    associatedtype O
    associatedtype E
    var handler: MyHandler<O,E>? { get }
}

public class MyAnnouncer {
    private let mapWeakObjects: NSPointerArray = NSPointerArray.weakObjects()
    public func add<L: MyListener>(listener: L) {
        let pointer = Unmanaged.passUnretained(listener).toOpaque()
        mapWeakObjects.addPointer(pointer)
    }
    public func search<O, E> (h:MyHandler<O,E>) -> [Int] {
        _ = mapWeakObjects.allObjects.filter { listener in
            if listener is MyListener { // Compilation failed
            }
            if let _ = listener as? MyListener { //Compilation error
            }
            if listener is MyListener.Type { //Compilation failed
            }
        }
        return [] // ultimate goal is to extract corresponding [MyListener.section].
    }
}

【问题讨论】:

    标签: swift swift-protocols conditional-operator associated-types


    【解决方案1】:

    不幸的是,Swift 不支持符合 AssociatedType 的协议。

    您应该尝试使用Type Erasure。一种方法是通过创建新的 AnyType 类来实现类型擦除。 这是释放类型擦除的另一种方法(来自互联网的示例

    protocol SpecialValue { /* some code*/ }
    
    protocol TypeErasedSpecialController {
      var typeErasedCurrentValue: SpecialValue? { get }
    }
    
    protocol SpecialController : TypeErasedSpecialController {
      associatedtype SpecialValueType : SpecialValue
      var currentValue: SpecialValueType? { get }
    }
    
    extension SpecialController {
      var typeErasedCurrentValue: SpecialValue? { return currentValue }
    }
    
    extension String : SpecialValue {}
    
    struct S : SpecialController {
      var currentValue: String?
    }
    
    var x: Any = S(currentValue: "Hello World!")
    if let sc = x as? TypeErasedSpecialController { // Now we can perform conformance
      print(sc.typeErasedCurrentValue) 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-02
      • 1970-01-01
      • 2021-10-13
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多