Swift:等价泛型类型

时间:2018-01-23 11:59:16

标签: ios swift generics types generic-collections

我一直在与Swift上的一些关于泛型的问题进行斗争,而且我找不到如何实现这一目标的方法:

  • 我有一个班级class Store<S: State>,其中State是一个简单的协议,它扩展了Equatable protocol State: Equatable
  • 我有一个班级Logger,我希望存储一个Stores数组,以跟踪每个更改,并将他们的State与旧值进行比较,以便检查每次迭代都会发生什么变化。

为此,我需要在记录器类中存储一个任意类型的商店数组。问题出现在我尝试使用val storeArray = [Store<Any>]时,它不起作用,因为Any不是Equatable类型,我需要它们来扩展Equatable或{{1能够比较它们之间的状态。

可以在Swift中实现这一点吗?或者找出另一种方法来比较2个项目,而不是通用扩展NSObject协议?

如果你想检查实施:

状态:

Equatable

商店:

protocol State: Equatable {
}

Vadian 的建议之后,我尝试将其移至具有关联类型的协议:

class Store<S: State> {

    private var _initialState: S
    private var _state: S
    private var processor = PublishSubject<S>()

    init(initialState: S) {
        _initialState = initialState
        _state = initialState
    }

    var state: S {
        get {
            return _state
        }
        set(value) {
            if (value != state) {
                _state = value
                processor.onNext(value)
            }
        }
    }

    func initialState() -> S {
        return _initialState
    }

    /// Initialize the store. Called after all stores instances are ready.
    func initialize() {
        //TODO Check if its possible to force an override over a method
        preconditionFailure("This method must be overridden")
    }
}

但是当我尝试创建protocol Store: class { associatedtype State : StateDelegate var processor : PublishSubject<State> { get } var _state : State { get set } var state: State { get set } func initialState() -> State func flowable() -> Observable<State> func initialize() -> Void } extension Store { var state: State { get { return _state } set(value) { if (value != state) { _state = value processor.onNext(value) } } } func flowable() -> Observable<State> { return processor.startWith(state) } func initialState() -> State { return State.init() } } 数组时,我会检索下一个错误: [Store]

1 个答案:

答案 0 :(得分:1)

我想我现在明白你的问题。这个解决方案怎么样:

不是让State符合Equatable,而是将自己的自定义相等检查添加到协议中;这样您就可以将状态存储在数组中(var states: [State])。缺点是你不能使用泛型,而是必须在代码中进行类型检查,就像过去一样。

例如,State协议的简单版本:

protocol State {
  func isEqualTo(_ other: State) -> Bool
}

您的具体状态类型必须实现isEqualTo并在测试相等性之前执行类型检查:

struct State1: State {
  var foo: String
  func isEqualTo(_ other: State) -> Bool {
    guard let state1 = other as? State1 else { return false }
    return self.foo == state1.foo
  }
}

现在,您可以将状态存储在数组中,例如检查是否已包含新状态:

let states: [State] = [ State1(foo: "hi"), State2(bar: 42), State1(foo: "bye")]
let newState = State2(bar: 42)
let containsNewState = states.contains { $0.isEqualTo(newState )}