[swift-evolution] [Pitch] Allow use associated type outside of its protocol

Xiaodi Wu xiaodi.wu at gmail.com
Sun Feb 19 17:14:50 CST 2017


On Sun, Feb 19, 2017 at 5:04 PM, 曹剑楠 via swift-evolution <
swift-evolution at swift.org> wrote:

> 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 }
>     }
> }
> ```
>

Sorry, I'm reading this quickly, but I'm confused as to why you're not
writing `var items: [Element.SectionItemType]`. That seems to be what you
want, no? `SectionProtocol.SectionItemType` has no constraints and, even if
the grammar allowed you to write it, would have to be equivalent to `Any`.

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
>
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170219/d357144d/attachment.html>


More information about the swift-evolution mailing list