参数类型与预期类型不符

时间:2019-09-17 19:00:31

标签: ios swift generics

我想要一个通用的UIPageViewControllerDataSource,它可以基于两个通用参数来完成其工作,例如:

protocol ItemDisplaying where Self: UIViewController {
  associatedtype T

  var item: T { get }

  init(item: T)
}

final class LinearPageDataSource<V: ItemDisplaying> {
  let items: [V.T]

  init(items: [V.T]) {}
}

但是,数据源中的方法如下:

private func indexOf(_ viewController: V) -> Int {
  return items.firstIndex(of: viewController.item) ?? NSNotFound
}

Argument of type V.T does not conform to expected type 'Equatable'出错。 因此,我明确添加了以下代码:class OnboardingContentViewController<T: Codable & Equatable>: UIViewController, ItemDisplaying,以便可以证明在ViewController中作为T传递的项的类型为Codable & Equatable

我陷入了要达到的目标,我想拥有一个数据源,该数据源需要一个至少为Codable & Equatable的项数组,并且我想保留一个通用可能会传入UIViewController类型。如何最好地做到这一点?

1 个答案:

答案 0 :(得分:0)

我没有注意到associatedtype不能引用其他协议,而必须引用具体类型。因此,以下工作原理:

protocol ItemDisplaying where Self: UIViewController {
  associatedtype T: Decodable & Equatable

  var item: T { get }

  init(item: T)
}
final class LinearPageDataSource<V: ItemDisplaying>: NSObject, UIPageViewControllerDataSource {
  let items: [V.T]

  init(items: [V.T]) {
    self.items = items
  }

  func contentViewController(atIndex index: Int) -> V? {
    return V.init(item: items[index])
  }
final class OnboardingContentViewController: UIViewController, ItemDisplaying {
  typealias T = OnboardingItem // this is a struct, conforming to Decodable and Equatable

  let item: T

  required init(item: T) {
    self.item = item
  }
}