简体   繁体   中英

Infer generic from any using protocol with associatedtype

i'm trying to make this code work

{ (tableview, originalItems, item, indexPath) in

    guard let matchingItem = originalItems.filter({ matching($0, with: item.itemIdentifier) }).first else {

        LogManager.Fatal.log("No item matching identifier : \(item.itemIdentifier)")

        return nil

    }
Some code
}

originalItems is [Any] and my function is

static func matching<T: SectionRowRepresentable>(_ item: T, with identifier: String) -> Bool where T.Identity == AnyItemRepresentable.Identity

How can I infer T from Any knowing the fact that SectionRowRepresentable has an associatedType Identity

public protocol SectionRowRepresentable: Equatable {

  associatedtype Identity: Hashable

  var itemIdentifier: String { get }

}

I've ended up doing like this

  static func filter<T: SectionRowRepresentable>(_ items: [Any], match identifier: String) -> T? where T.Identity == AnyItemRepresentable.Identity {

    return items
      .flatMap { $0 as? T }
      .filter { $0.identity == identifier }
      .first

  }

  static func tableviewCellFactory() -> TableViewCellFactoryBlock {

    return { (tableview, originalItems, item, indexPath) in

      if let movieItem = filter(originalItems, match: item.itemIdentifier) as MovieItem? {

        let adapter = TitleLabelViewAdapter(mapping: movieItem.identifier, title: movieItem.title)
        let factory = TableViewCellFactory<TitleLabelView>(identifier: movieItem.identifier,
                                                           reuseIdentifier: TitleLabelView.ReuseIdentifier,
                                                           adapter: adapter)

        return AnyTableViewCellFactory(factory)

      } else if let adItem = filter(originalItems, match: item.itemIdentifier) as NativeAdItem? {

        let reuseIdentifier = "\(TopImageBottomTitleLabelView.ReuseIdentifier) \(adItem.identifier)"
        let adapter = TopImageBottomTitleLabelViewAdapter(mapping: adItem.identifier, title: adItem.title)
        let factory = TableViewCellFactory<TopImageBottomTitleLabelView>(identifier: adItem.identifier,
                                                                         reuseIdentifier: reuseIdentifier,
                                                                         adapter: adapter)

        return AnyTableViewCellFactory(factory)

      }

      LogManager.Fatal.log("No item matching identifier : \(item.itemIdentifier)")

      return nil

    }

  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM