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

Xiaodi Wu xiaodi.wu at gmail.com
Sun Feb 19 17:42:18 CST 2017


That is a new feature in Swift 3.1.


On Sun, Feb 19, 2017 at 5:32 PM, 曹剑楠 <frogcjn at 163.com> wrote:

> Sorry about my typo:
>
> 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 extension Array where Element == Sectioned {
>
>
>     var itemsCount: Int {
>         return reduce(0) { (result, section) in result +
> section.items.count }
>     }
>
>
>     var items: [Element.Item] {
>         return self.flatMap { $0.items }
>     }
> }
>
> Allow extension Array with strict its Element with a struct type (may be
> generic) is highly wanted feature.
>
> 在 2017年2月20日,上午7:28,曹剑楠 <frogcjn at 163.com> 写道:
>
>
> OK, my fault. That solved the problem.
>
> var items: [Element.SectionItemType]
>>
>
> I should use this.
>
> How about to allow using generic type Section directly instead of declare
> a protocol
>
> ```Swift
> public extension Array where Element == Section {
>
>     var itemsCount: Int {
>         return reduce(0) { (result, section) in result +
> section.items.count }
>     }
>
>     var items: [Element.SectionItemType] {
>         return self.flatMap { $0.items }
>     }
> }
> ```
>
> 在 2017年2月20日,上午7:14,Xiaodi Wu <xiaodi.wu at gmail.com> 写道:
>
> 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/0b9f15d1/attachment.html>


More information about the swift-evolution mailing list