web-dev-qa-db-ja.com

Swiftのジェネリッククラスの継承

私は次のクラスを持っています:

class BaseCache<T: Equatable>: NSObject {

    var allEntities = [T]()

    // MARK: - Append

    func appendEntities(newEntities: [T]) {
        ....
    }
}

今度はそれをサブクラス化したいのですが、私のタイプが「プロトコル 'Equatable'に準拠していません」という厄介なエラーが発生します。 enter image description here

Swiftのジェネリックは、本当に苦痛のようです。

13
Andrey Gordeev

TrackingCacheのクラス定義が間違っています。一般的なパラメータを繰り返します。

class TrackingCache<AftershipTracking>: BaseCache<AftershipTracking> { }

省略してください:

class TrackingCache: BaseCache<AftershipTracking> { }

これにより、基になるSwiftエラーClasses derived from generic classes must also be generic。 AftershipTrackingであるか、AftershipTrackingから継承する必要があるタイプパラメータを指定することで、この問題を回避できます。

class TrackingCache<T: AftershipTracking>: BaseCache<AftershipTracking> { }

完全な例:

class BaseCache<T: Equatable>: NSObject {
  var items: [T] = []

  func appendItems( items: [T]) {
    self.items += items
    didAppendItems()
  }

  func didAppendItems() {} // for overriding
}

class AftershipTracking: NSObject {
  var identifier: Int
  init( identifier: Int) {
    self.identifier = identifier
    super.init()
  }
}

extension AftershipTracking: Equatable { }

func ==( lhs: AftershipTracking, rhs: AftershipTracking) -> Bool {
  return lhs.identifier == rhs.identifier
}

class TrackingCache<T: AftershipTracking>: BaseCache<AftershipTracking> {
  override func didAppendItems() {
    // do something
  }
}

let a = TrackingCache<AftershipTracking>()
let b = TrackingCache<AftershipTracking>()

a.appendItems( [AftershipTracking( identifier: 1)])
b.appendItems( [AftershipTracking( identifier: 1)])

let result = a.items == b.items // true
18
lassej

これはうまくいくはずです:<Swift 4>

class TrackingCache<T: AftershipTracking>: BaseCache<T>

もう一つの例:

protocol P {

}

class C: P {

}

class CS: C {

}

class L<T:P> {
    let c: T

    init(_ c: T) {
        self.c = c
    }
}

class LS<T:CS>:L<T> {

}

let i = LS(CS())

i.c

cCSになりました。

4
jimmy