Я пытаюсь реализовать какое-то одно решение для каждого обратного вызова в приложении. Поэтому я хочу, чтобы любой обратный вызов использовал один класс или, по крайней мере, семейство классов.Swift generics со значением по умолчанию
- Каждый обратный вызов может быть успешным или нет.
- Если он успешный, он может содержать некоторые результаты операции.
- Если это не так, он может содержать информацию о том, что не удалось.
Распространенное использование обратных вызовов выглядит следующим образом:
func foo(callback: ((success: Bool, result: Result?, error: Error?) -> Void)?) { }
Или:
func foo(success: ((result: Result) -> Void)?, failure: ((error: Error) -> Void)?) { }
мне не нравится ни один из них. Я хочу иметь одно элегантное решение для каждого обратного вызова. Я нашел что-то подобное в библиотеке Alamofire.
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))
}
Это решение это приятно. Но, как и в моем примере, нам не всегда нужно передавать любое значение или ошибку в качестве параметра. В любом случае, компилятор всегда должен знать, с какими должны быть общие параметры. Поэтому, даже если я не измеряю значение типа, я всегда должен положить туда по крайней мере Any
или AnyObject
. Это сложно.
Я попытался изменить его с помощью класса решения:
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))
}
Он имеет такую же функциональность. Но даже таким образом это не решило мою проблему. Вы не можете просто написать вот так:
CallbackResult<_, Error>
Это не сработает.
Возможно, кто-нибудь знает решение моей проблемы? Какой-то способ поставить значение по умолчанию, возможно, не писать Any
каждый раз? Или на данный момент существует только уродливый способ использования этого подхода?
Он работает частично. Когда я использую это: typealias AnyCallback = (AnyResult ) ->(), я получаю сообщение об ошибке «Сегментация»: 11 –