2016-09-14 102 views
2

我试图为应用程序中的每个回调实现一些单一的解决方案。所以我希望任何回调都使用同一个类,或者至少一个类。具有默认值的Swift仿制药

  • 每个回调都可以成功或不成功。
  • 如果成功,它可以包含一些操作结果 。
  • 如果不是,它可以包含有关它失败的信息。

常见的回调用法是这样的:

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)) 
    } 

这个解决方案很好。但就像在我的例子中那样,我们并不总是需要通过任何值或错误作为参数。无论如何,编译器总是需要知道什么类型的泛型参数应该是。所以即使我不计算什么类型的值,我总是应该至少在那里存储AnyAnyObject。它过于复杂。

我试着级的解决方案来改变它:

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?或者现在只有使用这种方法的丑陋方式?

回答

1

Swift 3 added generic type aliases。这些可能会帮助您避免每次输入所有类型。

实施例:

typealias AnyResult<E> = CallbackResult<Any, E> 
typealias AnyCallback<E> = (AnyResult<E>) ->() 

func foo(callback: AnyCallback<String>?) { 
    callback?(.failure(error: "Ouch!")) 
} 

foo() { result in 
    if result.isSuccess { 
     // ... 
    } 
} 
+0

它的工作原理部分。当我使用这个:typealias AnyCallback =(AnyResult ) - >(),我得到一个错误'Segmentation'错误:11 –