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...@gmail.com> 写道: > > On Sun, Feb 19, 2017 at 5:04 PM, 曹剑楠 via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@swift.org> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution> > >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution