2016-09-14 8 views
2

私は、アプリケーションの各コールバックに対していくつかの単一のソリューションを実装しようとしています。だから私は、コールバックが同じクラス、または少なくともクラスのファミリーを使用したい。デフォルト値のスウィフトジェネリック

  • すべてのコールバックが成功するかどうか。
  • 成功した場合は、何らかの操作結果が含まれている にすることができます。
  • そうでない場合は、何が失敗したかに関する情報を含むことができます。

共通のコールバックの使用は次のようになります。

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と書くのではないでしょうか?または、今のところ、そのアプローチを使用する醜い方法がありますか?

答えて

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 ) - >()、エラーが発生しました 'セグメンテーション'エラー:11 –