[swift-evolution] [Pitch] Allow use associated type outside of its protocol
曹剑楠
frogcjn at 163.com
Sun Feb 19 17:04:15 CST 2017
Hi All,
I’m coding for section like data structure.
For example:
I have an Album struct, which has many MediaItems.
It has a sectioned property called "sectionedMediaItemInfos", which is an array of sections.
Each section represents for a disc, and has an "items" array contains all MedaItems in that disc.
The define code is like:
```Swift
public struct Album {
public let sectionedMediaItemInfos: [Sectioned<MediaItemInfo>]?
}
public struct Sectioned<Item> : SectionProtocol {
public let title: String?
public let items: [Item]
public init() {
items = []
title = nil
}
}
public protocol SectionProtocol {
associatedtype SectionItemType
var items: [SectionItemType] { get }
}
```
Now I want to define some extra properties for sections array, like
"sectionMediaItemInfos"."itemsCount" that count all items in each sections.
So I can write that extension:
```Swift
public extension Array where Element : SectionProtocol {
var itemsCount: Int {
return reduce(0) { (result, section) in result + section.items.count }
}
}
```
So I can get my itemsCount with code like:
```Swift
album.sectionedMediaItemInfos.itemsCount
```
That looks good.
Then I want to define code to return all items in this sectioned property.
```Swift
public extension Array where Element : SectionProtocol {
var items: [SectionProtocol.SectionItemType] {
return .flatMap { $0.items }
}
}
```
This doesn’t work. It reported as "Cannot use associated type 'SectionItemType' outside of its protocol"
The only way to achieve my goals is to untyped the extended "items" property:
```Swift
public extension Array where Element : SectionProtocol {
var items: [Any] {
return self.flatMap { $0.items }
}
}
```
Which is not perfect for this case.
So in this special case, I think allow use associated type outside of its protocol is necessary.
And we may allow define protocol with generic type. That would be more convenient.
```Swift
public struct Album {
public let sectionedMediaItemInfos: [Sectioned<MediaItemInfo>]?
}
public struct Sectioned<Item> : SectionProtocol {
public let title: String?
public let items: [Item]
public init() {
items = []
title = nil
}
}
public protocol SectionProtocol<SectionItemType> {
var items: [SectionItemType] { get }
}
public extension Array where Element : SectionProtocol {
var items: [Element.SectionItemType] {
return self.flatMap { $0.items }
}
}
```
Thank all!
Jiannan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170220/b4f6cc35/attachment.html>
More information about the swift-evolution
mailing list