antitypical/Resultの良いところ
Swiftに慣れてくると!
を避けたくなりますが、!
を書きたくなるようなケースもあります。
func someFunc(handler: (String?, NSError?) -> Void)
someFunc { string, error in
if error != nil {
} else {
// ここで!を使いたくなる
}
}
Resultを使って以下のように書き直すと!
を避けられます。
func someFunc(handler: Result<String, NSError>) -> Void)
someFunc { result in
switch result {
case .Success(let box): // box.value: String
case .Failure(let box): // box.value: NSError
}
}
また、元のコードのvalue, errorは両方ともOptionalなので、以下の4つの組み合わせが存在します。
- None, None
- None, Some
- Some, None
- Some, Some
元のコードは(None, None)と(Some, Some)を考慮していません。 つまり、実行時には(None, Some)と(Some, None)の2パターンしか存在しないという約束を前提としたコードとなっています。 Resultを利用するとそのような約束を型で表すことができ、2パターンしか存在しないことがコンパイル時に保証されるようになります。
Cocoaの伝統的なメソッドに対してもResultを使用できます。
var error: NSError?
let object = NSJSONSerialization.dataWithJSONObject(object, options: options, error: &error)
let result = try { error in
NSJSONSerialization.dataWithJSONObject(object, options: options, error: error)
}
map, flatMapもあるので連続した処理もシンプルに書けます。
let connectionResult = try { error in
NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error: error)
}
let parseResult = connectionResult.flatMap { data in
try { error in
NSJSONSerialization.JSONObjectWithData(data, options: options, error: error)
}
}
APIKitでもantitypical/Resultを活用しています。