J'expérimente une architecture basée sur des messages dans Swift. J'essaie de faire quelque chose de similaire à l'architecture d'Elm, par exemple. Voici comment mon code ressemble:Messages génériques dans une architecture basée sur des messages
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 []
}
}
}
Ainsi, l'état est modélisé par State
et vous pouvez le changer en envoyant Message
s. S'il y a des effets secondaires à calculer, ils sont retournés sous la forme d'un message SideEffect
et seront pris en charge par quelqu'un d'autre. Chaque message SideEffect
prend un argument "callback", un Message
à envoyer lorsque l'effet secondaire est terminé. Cela fonctionne très bien. Maintenant, et si je veux avoir un message d'effet secondaire générique? Je voudrais avoir quelque chose comme ceci:
struct Request<ReturnType> { … }
et ont un effet secondaire lié à charger la demande et retourner une valeur de type ReturnType
:
enum SideEffect<Message> {
case sendRequest(Request<T>, (T) -> Message)
}
Mais ce (évidemment) ne compile pas , car le case
devrait être générique sur T
. Je ne peux pas faire l'ensemble SideEffect
générique sur T
, car il y a d'autres effets secondaires qui n'ont rien à voir avec T
.
Puis-je créer en quelque sorte un message SideEffect
avec un Request<T>
qui enverrait plus tard un Message
avec ? (Je pense que je veux quelque chose comme this feature discussed on swift-evolution.)
Que diriez-vous que nous faisons un protocole 'Returnable' et faire les' ReturnType' sont conformes à ce protocole ? Ensuite, nous pouvons également étendre d'autres types, comme 'String', pour se conformer à ce protocole. – sCha
Vous voudrez taper "T", en général cela peut être fait avec des fermetures (par exemple vous faites une fermeture qui exécute la requête et passe ensuite le résultat à votre fonction qui donne alors un message, cachant ainsi le type de ' T' du monde extérieur). Je ne suis pas du tout familier avec l'architecture d'Elm et je ne suis donc pas sûr de savoir comment vous attendez que 'Request' soit implémenté, mais [quelque chose comme ça] (http://swift.sandbox.bluemix.net/#/ repl/59e15aad6cbea87f72c470cc) être viable? – Hamish
Hamish à la rescousse à nouveau! Je pense que c'est exactement ce dont j'avais besoin. Je battais autour de l'effacement de type, mais apparemment je ne me suis pas habitué au concept alors je n'ai pas trouvé la solution. Merci beaucoup! J'ai marqué la question pour que votre commentaire soit converti en une réponse. – zoul