声明具有属性返回值CollectionType的Swift协议<;Int>;?

声明具有属性返回值CollectionType的Swift协议<;Int>;?,swift,protocols,Swift,Protocols,有点像 protocol A { var intCollection: CollectionType<Int> { get } } 在Swift 2.1中是否可能 Swift 4的更新 Swift 4现在支持此功能 您不能像您的问题中那样直截了当地执行此操作,在使用协议作为类型定义的主题上,这里有几个线程,内容本身包含自身或关联的类型需求(结果:这是不允许的)。参见,例如,螺纹 现在,对于上面的例子,您可以进行以下变通,不过,也许可以模仿您正在寻找的行为 protocol

有点像

protocol A {
    var intCollection: CollectionType<Int> { get }
}
在Swift 2.1中是否可能


Swift 4的更新


Swift 4现在支持此功能

您不能像您的问题中那样直截了当地执行此操作,在使用协议作为类型定义的主题上,这里有几个线程,内容本身包含自身或关联的类型需求(结果:这是不允许的)。参见,例如,螺纹

现在,对于上面的例子,您可以进行以下变通,不过,也许可以模仿您正在寻找的行为

protocol A {
    typealias MyCollectionType
    typealias MyElementType
    func getMyCollection() -> MyCollectionType
    func printMyCollectionType()
    func largestValue() -> MyElementType?
}

struct B<U: Comparable, T: CollectionType where T.Generator.Element == U>: A {
    typealias MyCollectionType = T
    typealias MyElementType = U
    var myCollection : MyCollectionType

    init(coll: MyCollectionType) {
        myCollection = coll
    }

    func getMyCollection() -> MyCollectionType {
        return myCollection
    }

    func printMyCollectionType() {
        print(myCollection.dynamicType)
    }

    func largestValue() -> MyElementType? {
        guard var largestSoFar = myCollection.first else {
            return nil
        }
        for item in myCollection {
            if item > largestSoFar {
                largestSoFar = item
            }
        }
        return largestSoFar
    }
}

不是作为一个嵌套协议,但是使用类型擦除器(“Any”结构)非常简单

这并不理想,因为这意味着您可以使用错误类型的集合类型创建
A
。他们只是没有一个
sum
方法。您还会发现自己在很多地方重复“where IntCollection.Generator.Element==Int”


根据我的经验,这样做很少值得,您很快就会回到阵列(无论如何,阵列是主要的集合类型)。但是当你需要的时候,这是两种主要的方法。这是我们今天最好的回答。

这可能回答了你的问题:我读了一些问题和答案,解决办法并不新奇。我本人有OOP背景,在Swift中我学到了(艰难的方式…)当事情开始变得混乱时,也许应该重新考虑我对原始问题的处理方法:面向协议编程(protocol-oriented programming,POP)与面向对象编程(OOP)有很多相似之处,但仍然有很大不同,我相信Swift的作者在编写该语言时就考虑到了这一点。因此:如果你认为事情开始变得一团糟,我的建议是回到原点,尝试找到解决问题或任务的替代方法。
protocol A {
    typealias MyCollectionType
    typealias MyElementType
    func getMyCollection() -> MyCollectionType
    func printMyCollectionType()
    func largestValue() -> MyElementType?
}

struct B<U: Comparable, T: CollectionType where T.Generator.Element == U>: A {
    typealias MyCollectionType = T
    typealias MyElementType = U
    var myCollection : MyCollectionType

    init(coll: MyCollectionType) {
        myCollection = coll
    }

    func getMyCollection() -> MyCollectionType {
        return myCollection
    }

    func printMyCollectionType() {
        print(myCollection.dynamicType)
    }

    func largestValue() -> MyElementType? {
        guard var largestSoFar = myCollection.first else {
            return nil
        }
        for item in myCollection {
            if item > largestSoFar {
                largestSoFar = item
            }
        }
        return largestSoFar
    }
}
/* Examples */
var myArr = B<Int, Array<Int>>(coll: [1, 2, 3])
var mySet = B<Int, Set<Int>>(coll: [10, 20, 30])
var myRange = B<Int, Range<Int>>(coll: 5...10)
var myStrArr = B<String, Array<String>>(coll: ["a", "c", "b"])

myArr.printMyCollectionType()    // Array<Int>
mySet.printMyCollectionType()    // Set<Int>
myRange.printMyCollectionType()  // Range<Int>
myStrArr.printMyCollectionType() // Array<String>

/* generic T type constrained to protocol 'A' */
func printLargestValue<T: A>(coll: T) {
    print(coll.largestValue() ?? "Empty collection")
}

printLargestValue(myArr)    // 3
printLargestValue(mySet)    // 30
printLargestValue(myRange)  // 10
printLargestValue(myStrArr) // c
protocol A {
    var intCollection: AnyRandomAccessCollection<Int> { get }
}
protocol A {
    typealias IntCollection: CollectionType
    var intCollection: IntCollection { get }
}

extension A where IntCollection.Generator.Element == Int {
    func sum() -> Int {
        return intCollection.reduce(0, combine: +)
    }
}