【问题标题】:Swift 2.0: Creating a Collection Type of Objects that conform to a Generic ProtocolSwift 2.0:创建符合通用协议的对象集合类型
【发布时间】:2015-09-11 00:44:41
【问题描述】:

例如:

protocol SomeProtocol {
    typealias T
    func doSomething(something: T)
}
let a = Array<SomeProtocol>()

我想要一个数组,它是一个符合SomeProtocol 的对象数组。这在理论上看起来不错,但我收到以下错误消息:

不能用作通用约束,因为它包含关联的 类型要求。

而且我想这是有道理的,毕竟 Array 也是一个泛型结构,因此编译器将无法弄清楚 SomeProtocolArray 都是泛型的实际类型。

所以我的问题是——我觉得我应该能够拥有一组符合SomeProtocol 的对象——这在目前的 Swift 2.0 中是否可行?我是不是想错了?

【问题讨论】:

    标签: swift swift2 swift-protocols


    【解决方案1】:

    此错误消息的原因是如果您的 Array 声明有效,则会出现以下问题:

    protocol SomeProtocol {
        typealias T
        func doSomething(something: T)
    }
    // has already some values
    let a: Array<SomeProtocol> = [...]
    
    // what type should be passed as parameter?
    // the type of T in SomeProtocol is not defined
    a[0].doSomething(...)
    

    作为解决方法,您可以为任何类型的SomeProtocol 创建一个通用包装结构,这样您就可以指定T 的类型(如在 Swift 标准库 AnyGenerator、AnySequence 中...)。

    struct AnySomeProtocol<T>: SomeProtocol {
        let _doSomething: T -> ()
        // can only be initialized with a value of type SomeProtocol
        init<Base: SomeProtocol where Base.T == T>(_ base: Base) {
            _doSomething = base.doSomething
        }
        func doSomething(something: T) {
            _doSomething(something)
        }
    }
    

    现在您使用[AnySomeProtocol&lt;T&gt;] 类型的数组(将T 替换为您想要的任何类型)并在附加元素之前将其转换为AnySomeProtocol

    var array = [AnySomeProtocol<String>]()
    array.append(AnySomeProtocol(someType))
    
    // doSomething can only be called with a string 
    array[0].doSomething("a string")
    

    【讨论】:

      【解决方案2】:

      不,这在 Swift 2 中是不可能的。在指定泛型参数之前,不能使用泛型类型。对于泛型类、结构体和枚举,它们的泛型参数可以在使用时同时指定。例如可以像这样使用数组:

      let anArray: [String]
      

      这里Array的泛型参数在Array用作变量类型时被指定为String

      但是,泛型协议(具有关联类型的协议,命名为 typealias)只能在具体类型符合它时指定其关联类型。当您使用泛型协议作为变量的类型(如泛型类、结构或枚举)时,您无法提供关联的类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-02
        • 2015-09-12
        • 1970-01-01
        • 2014-12-09
        • 1970-01-01
        相关资源
        最近更新 更多