Swift: an array of equisymmetric type

I've been struggling with some generic issues in Swift in recent days, and I haven't found a way to figure out how to do this:

  • I have a class class Store<S: State>where Stateis a simple protocol that extends Equatable protocol State: Equatable.
  • I have a class Loggerwhere I want to save an array Storesin order to track each change on them and compare them Statewith old values, being able to check what changes are on each iteration.

To do this, I need to save the Any Kind of Store array in my logger class. The problem arises when I try to use val storeArray = [Store<Any>], it does not work, because Any is not a type Equatable, and I will need their extension Equatableor NSObject, in order to be able to compare the states between them.

Can this be achieved in Swift? Or find out another way to compare 2 elements without creating a common protocol version Equatable?

If you want to check the implementation:

Condition:

protocol State: Equatable {
}

Score:

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

After the Vadian sentence , I tried moving it to the protocol with the associated type:

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

But I get the following error when I try to create an array [Store]: Protocol 'Store' can only be used as a generic constraint because it has Self or associated type requirements

+4
source
1

, . :

, State Equatable, ; (var states: [State]). , generics, , , .

, 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 )}
+1

Source: https://habr.com/ru/post/1692575/


All Articles