簡體   English   中英

Swift:相等的泛型類型數組

[英]Swift: Array of equatable generic type

我是在最后幾天與Swift上有關泛型的一些問題作斗爭,但我找不到找到解決方法的方法:

  • 我有一個類class Store<S: State> ,其中State是擴展Equatable protocol State: Equatable的簡單協議。
  • 我有一個Logger類,我想在其中存儲一組Stores來跟蹤它們的每個更改,並將它們的State與它們的舊值進行比較,從而能夠檢查每次迭代中的更改。

為此,我需要在logger類中存儲任何類型的存儲數組。 當我嘗試使用val storeArray = [Store<Any>] ,問題就來了,這是行不通的,因為Any不是Equatable類型,我將需要它們擴展EquatableNSObject以便能夠在兩個之間比較狀態他們。

可以在Swift中實現嗎? 還是找到另一種比較兩個項目而不使泛型擴展Equatable協議的方法?

如果您想檢查實現:

狀態:

protocol State: Equatable {
}

店鋪:

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")
    }
}

根據Vadian的建議,我嘗試將其移至關聯類型的協議中:

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]數組時,我檢索了下一個錯誤: Protocol 'Store' can only be used as a generic constraint because it has Self or associated type requirements

我想我現在明白你的問題了。 該解決方案如何:

不必讓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 )}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM