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

曹剑楠 frogcjn at 163.com
Sun Feb 19 17:53:49 CST 2017


Thanks! Waiting for the new version.

> 在 2017年2月20日,上午7:42,Xiaodi Wu <xiaodi.wu at gmail.com> 写道:
> 
> That is a new feature in Swift 3.1.
> 
> 
> On Sun, Feb 19, 2017 at 5:32 PM, 曹剑楠 <frogcjn at 163.com <mailto: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 <mailto: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 <mailto:xiaodi.wu at gmail.com>> 写道:
>>> 
>>> On Sun, Feb 19, 2017 at 5:04 PM, 曹剑楠 via swift-evolution <swift-evolution at swift.org <mailto: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 <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> 
>> 
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170220/63c47f37/attachment-0001.html>


More information about the swift-evolution mailing list