Ich versuche, eine einzelne Lösung für jeden Callback in der Anwendung zu implementieren. Daher möchte ich, dass jeder Callback die gleiche Klasse oder zumindest eine Familie von Klassen verwendet.Swift Generics mit Standardwert
- Jeder Rückruf kann erfolgreich sein oder nicht.
- Wenn es erfolgreich ist, kann es ein Ergebnis der Operation enthalten.
- Wenn nicht, kann es Informationen darüber enthalten, was fehlgeschlagen ist.
Die gemeinsame Nutzung Rückrufe sieht wie folgt aus:
func foo(callback: ((success: Bool, result: Result?, error: Error?) -> Void)?) { }
Oder:
func foo(success: ((result: Result) -> Void)?, failure: ((error: Error) -> Void)?) { }
ich nicht einer von ihnen mögen. Ich möchte für jeden Rückruf eine elegante Lösung haben. Ich habe etwas ähnliches in Alamofire Bibliothek gefunden.
enum CallbackResult<T, V> {
case success(value: T?)
case failure(error: V?)
var isSuccess: Bool {
switch self {
case .success: return true
case .failure: return false
}
}
}
func foo(callback: ((result: CallbackResult<Any, AnyObject>) -> Void)?) {
callback?(result: .success(value: nil))
}
Diese Lösung ist nett. Aber wie in meinem Beispiel müssen wir nicht immer irgendeinen Wert oder Fehler als Parameter übergeben. Wie auch immer, der Compiler muss immer wissen, von welchem Typ generische Parameter sein sollten. Also selbst wenn ich nicht messe, welcher Typ Wert ist, sollte ich immer mindestens Any
oder AnyObject
angeben. Es ist zu kompliziert.
Ich habe versucht, es mit Klasse-Lösung zu ändern:
class CallbackResult<T, V> {
let isSuccess: Bool
let value: T?
let error: V?
fileprivate init(success: Bool, value: T? = nil, error: V? = nil) {
self.isSuccess = success
self.value = value
self.error = error
}
static func success(value: T? = nil) -> CallbackResult {
return CallbackResult(success: true, value: value)
}
static func failure(error: V? = nil) -> CallbackResult {
return CallbackResult(success: false, error: error)
}
}
func foo(callback: ((result: CallbackResult<Any, AnyObject>) -> Void)?) {
callback?(result: CallbackResult.success(value: nil))
}
es die gleiche Funktionalität. Aber auch so hat es mein Problem nicht gelöst. Sie können nicht einfach so schreiben:
CallbackResult<_, Error>
Es wird nicht funktionieren.
Vielleicht jemand Lösung meines Problems kennen? Irgendeine Möglichkeit, den Standardwert zu setzen^um nicht jedes Mal Any
zu schreiben? Oder für den Moment gibt es nur hässliche Art, diesen Ansatz zu verwenden?
Es teilweise funktioniert. Wenn ich dies benutze: typealias AnyCallback = (AnyResult ) ->(), bekomme ich einen Fehler 'Segmentierung' Fehler: 11 –