2016-12-07 126 views
0

我有一個類StateMachine<A>如何使用SWIFT協議與泛型方法和泛型類型

final class StateMachine<A> { 

    private var previousState: State? = nil 
    private var currentState: State 
    private var content: A? 
    var delegate: StateMachineDelegate? 
    var state: State = .loading { 
     didSet { 
      previousState = currentState 
      currentState = state 
     } 
    } 

    init(currentState: State, delegate: StateMachineDelegate?) { 
     self.currentState = currentState 
    } 
} 

和委託協議StateMachineDelegate

protocol StateMachineDelegate { 
    func updateWith(content: A) 
} 

我想表達的是,如果創建的StateMachine對於類型A,代表應該實現方法func updateWith(content: A),它接受一個相同類型A的參數。這可能嗎?

+2

代碼有很多問題,現在:你不能把嵌套類型泛型('枚舉State');你必須初始化'init'中的所有非可選屬性;你必須在委託協議中指定'associatedtype'。 – user28434

回答

2

你會實現你通過添加其他類型的參數要求的東西:

final class StateMachine<A, Delegate: StateMachineDelegate> where Delegate.A == A { 

    private var previousState: State? = nil 
    private var currentState: State 
    private var content: A? 
    var delegate: Delegate? 
    var state: State = .loading { 
     didSet { 
      previousState = currentState 
      currentState = state 
      delegate?.updateWith(content: state) 
     } 
    } 

    init(currentState: State, delegate: Delegate?) { 
     self.currentState = currentState 
    } 
} 

protocol StateMachineDelegate { 
    associatedtype A 
    func updateWith(content: A) 
} 

但我不會做這種方式。如果您的代理真的只是一個更新的方法,那麼閉包是一個更好的解決方案:

final class StateMachine<A> {  
    // ... 
    private var content: A? 
    var notify: (A) -> Void 

    var state: State = .loading { 
     didSet { 
      previousState = currentState 
      currentState = state 
      notify(state) 
     } 
    } 

    init(currentState: State, notify: @escaping (A) -> Void) { 
     self.currentState = currentState 
     self.notify = notify 
    } 
} 
+0

Excellant答案!謝謝。 –