声明具有属性返回值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: +)
}
}