代码之家  ›  专栏  ›  技术社区  ›  J. Doe

创建具有受约束关联类型的协议数组

  •  3
  • J. Doe  · 技术社区  · 6 年前

    这是使用类型擦除创建具有关联类型的协议数组的基本示例:

    protocol ProtocolA {
        associatedtype T
    
        func doSomething() -> T
    }
    
    struct AnyProtocolA<T>: ProtocolA {
        private let _doSomething: (() -> T)
    
        init<U: ProtocolA>(someProtocolA: U) where U.T == T {
            _doSomething = someProtocolA.doSomething
        }
    
        func doSomething() -> T {
            return _doSomething()
        }
    }
    

    创建一个数组并不难:

    let x: [AnyProtocolA<Any>] = []
    

    有什么方法可以创建一个具有相关类型的协议数组 受到限制的 ? 这就是我尝试过的:

    protocol Validateable {
        // I removed the functions and properties here to omit unreleveant code.
    }
    
    protocol ProtocolA {
        associatedtype T: Validateable
    
        func doSomething() -> T
    }
    
    struct AnyProtocolA<T: Validateable>: ProtocolA {
        private let _doSomething: (() -> T)
    
        init<U: ProtocolA>(someProtocolA: U) where U.T == T {
            _doSomething = someProtocolA.doSomething
        }
    
        func doSomething() -> T {
            return _doSomething()
        }
    }
    

    它编译了!但它不是打败了现在制造一系列原始可乐的机会吗?现在我不能在数组中使用type Any作为占位符。

    如何创建一个数组 安普罗托科拉 哪个具有受约束的关联类型?有可能吗?从那以后就没用了 Any 当然不符合 Validateable :

    设x:[AnyProtocolA<Any>]=[]
    

    任何扩展都无法完成:

    extension Any: Validateable {} // Non nominal type error
    

    编辑: 我想我已经找到了,只需键入擦除协议即可验证:

    protocol Validateable {
        // I removed the functions and properties here to omit unreleveant code.
    }
    
    protocol ProtocolA {
        associatedtype T: Validateable
    
        func doSomething() -> T
    }
    
    struct AnyProtocolA<T: Validateable>: ProtocolA {
        private let _doSomething: (() -> T)
    
        init<U: ProtocolA>(someProtocolA: U) where U.T == T {
            _doSomething = someProtocolA.doSomething
        }
    
        func doSomething() -> T {
            return _doSomething()
        }
    }
    
    struct AnyValidateable<T>: Validateable {}
    

    现在我可以用它作为:

    let x: [AnyProtocolA<AnyValidateable<Any>>] = []
    

    任何更好的答案都是受欢迎的:)

    0 回复  |  直到 6 年前