我正在Swift中試驗基於消息的體系結構。例如,我正在嘗試類似於Elm Architecture。這是我的代碼的外觀:基於消息的體系結構中的通用消息
enum SideEffect<Message> {
case sendRequest((String) -> Message)
}
protocol Component {
associatedtype Message
mutating func send(msg: Message) -> [SideEffect<Message>]
}
struct State: Component {
var something: String?
enum Message {
case downloadSomething
case receiveResponse(String)
}
mutating func send(msg: Message) -> [SideEffect<Message>] {
switch msg {
case .downloadSomething:
return [.sendRequest(Message.receiveResponse)]
case .receiveResponse(let response):
something = response
return []
}
}
}
所以狀態由State
建模,您可以通過發送Message
換換口味吧。如果計算有任何副作用,它們將作爲SideEffect
消息返回,並由其他人處理。每個SideEffect
消息都有一個「回調」參數,當副作用完成時發送Message
。這很好。
現在,如果我想要一個通用的副作用信息呢?我想有這樣的事情:
struct Request<ReturnType> { … }
而且具有相關的副作用加載請求並返回ReturnType
類型的值:
enum SideEffect<Message> {
case sendRequest(Request<T>, (T) -> Message)
}
但這個(顯然)不會編譯,因爲case
將不得不通過T
。我不能使整個SideEffect
通用T
,因爲有其他副作用,與T
沒有任何關係。
我可以以某種方式創建一個SideEffect
消息與Request<T>
,稍後將派遣Message
與T
? (我想我想要類似this feature discussed on swift-evolution。)
怎麼樣,我們做一個協議'Returnable',使'ReturnType'符合本協議?然後我們也可以擴展其他類型,比如'String',以符合這個協議。 – sCha
您需要鍵入擦除'T',通常這可以通過關閉來完成(例如,您執行一個閉包來執行請求,然後將結果傳遞給您的函數,然後產生一條消息,從而隱藏' T'來自外部世界)。我完全不熟悉Elm架構,因此我不確定你如何期待'Request'被實現,但會[像這樣的東西](http://swift.sandbox.bluemix.net/#/ repl/59e15aad6cbea87f72c470cc)是否可行? – Hamish
再次趕緊救援!我認爲這正是我需要的。我在類型擦除時捱打,但顯然我不太習慣這個概念,所以我沒有想出解決方案。非常感謝你!我已將此問題標記爲將您的評論轉換爲答案。 – zoul