[swift-users] Optional generics question
Slava Pestov
spestov at apple.com
Thu Jun 8 22:57:16 CDT 2017
> On Jun 8, 2017, at 11:11 AM, Joel Loeshelle via swift-users <swift-users at swift.org> wrote:
>
> Hi all,
>
> Is there any support for having an optional type in an initializer? My use case is I want to have a struct SectionWrapper that includes information about a Collection View Section. So you can pass the CellType, Cell Data Source, and an Optional HeaderType and HeaderDataSource if there is a Section Header. Here's the code. I first have a protocol ViewModelConfigurable that the Cell and Header subclasses conform to:
>
> protocol ViewModelConfigurable
> {
> associatedtype ViewModelType
>
> func configure(with viewModel : ViewModelType);
> }
>
> class TestCell : UICollectionViewCell, ViewModelConfigurable
> {
> typealias ViewModelType = String
> func configure(with viewModel: String) {
> //todo
> }
> }
>
> class HeaderFooter : UICollectionReusableView, ViewModelConfigurable
> {
> typealias ViewModelType = String
> func configure(with viewModel: String) {
> //todo
> }
> }
>
> I then have a SectionWrapper struct where I want to initialize with a concrete UICollectionViewCell type that conforms to ViewModelType and pass the associated dataSource which must be an array of ViewModelType. I also want to have the ability to pass an optional UICollectionReusableView type that conforms to ViewModelType with the associated dataSource. You could then pass nil if this section does not have a Header. See below:
>
> struct SectionWrapper
> {
> let cellConfigure: (UICollectionViewCell, Int) -> ()
> let headerConfigure: ((UICollectionReusableView) -> ())?
>
> init<ActualCellType : UICollectionViewCell & ViewModelConfigurable, HeaderType : UICollectionReusableView & ViewModelConfigurable>(cellType : ActualCellType.Type, cellDataSource : [ActualCellType.ViewModelType], headerType : (HeaderType.Type)?, headerDataSource : (HeaderType.ViewModelType)?)
> {
> self.cellConfigure = { cell, index in
> (cell as! ActualCellType).configure(with: cellDataSource[index])
> }
>
> if let headerDataSource = headerDataSource
> {
> self.headerConfigure = { header in
> (header as! HeaderType).configure(with: headerDataSource);
> }
> }
> else
> {
> self.headerConfigure = nil
> }
> }
> }
>
> If I pass nil for headerType and headerDataSource, I get the following error:
> error: Swift4Test.playground:86:31: error: generic parameter 'ActualCellType' could not be inferred
> let noHeader = SectionWrapper.init(cellType: TestCell.self, cellDataSource: ["Test"], headerType: nil, headerDataSource: nil) //Gives error
>
>
> let header = SectionWrapper.init(cellType: TestCell.self, cellDataSource: ["Test"], headerType: HeaderFooter.self, headerDataSource: "Header") //No error
>
> let noHeader = SectionWrapper.init(cellType: TestCell.self, cellDataSource: ["Test"], headerType: nil, headerDataSource: nil) //Gives error
>
>
> I have also attached the Playground that I'm working through. Please let me know if you have any questions and thanks in advance for your help!
You could overload SectionWrapper.init(), providing two versions: one takes non-optional headerType and headerDataSource parameters, and the other does not take them at all, and only has a single generic parameter for ActualCellType.
Unfortunately we don’t support explicit specialization on function calls right now; if we did, you could write SectionWrapper.init<T, U> to explicitly bind the generic arguments.
Slava
> <Swift4Test.playground.zip>_______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170608/f6b9b388/attachment.html>
More information about the swift-users
mailing list