10
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swift|ResultのResultがResult.Resultとして使えない(Alamofire.Resultと併用でハマった)

Last updated at Posted at 2016-03-21

そもそもタイトルが何言ってるかよくわかんない感じですが、ResultのResultがResult.Resultとして使えず、しばらく原因がわからずハマりましたが、Resultのissueで紹介されていた回避策で一旦解決できたのでメモ。(ほぼ下記issueの紹介です)
結論としてはSwiftのバグのようなのでこの回避策以外ではとりあえずはどうにもならなそう。

"Result"で謎のエラー

AlamofireResultを同じファイルにimportして使っている場合に、Reference to generic type 'Result' requires arguments in <...>というエラーが発生しました。

たとえば、下記のようなsomeResult()があったとします。
ResultはResult<T, Error: ErrorType>、Alamofireも独自でResult<Value, Error: ErrorType>を定義しているので、AlamofireでもResultでもこのsomeResult()は成立します。

import Alamofire
import Result

func someResult(string: String) -> Result<String, Error> {
    return .Success(string)
}

enum Error: ErrorType {
    case SomeError
}

ただ、どちらもimportされている場合には、あたりまえですがどちらのResultかわからないのでエラーがでます。
'Result' is ambiguous for type lookup in this context

png

そこで、このsomeResult()ではResultのResultを返すものとして明示し、下記のように修正します。

import Alamofire
import Result

func someResult(value: Any) -> Result.Result<Any, Error> {
    return .Success(value)
}

何だ簡単、これでOK、と思いきや…
Reference to generic type 'Result' requires arguments in <...>

png

な、なんと…。:fearful:

試しにこれをAlamofire.Resultに変更してみます。

func someResult(value: Any) -> Alamofire.Result<Any, Error> {
    return .Success(value)
}

png

だ、大丈夫だ…。(そりゃそうだ)

原因

冒頭でも記載しましたが、どうもSwiftのバグが原因のようです。

こちらで報告されていますが、Setという名前のフレームワークの中に、同名Setのジェネリクス型が定義されている場合に、Set.Setとして呼び出すとSwiftがいい感じに解釈してくれないために、エラーが発生しちゃうよ!というもので、Resultでもこれと同じことが発生しているようです。

回避策

先ほどのissueで紹介されている回避策では、ResultをResultResultとしてラップしたものを別ファイルに定義して、それをResult.Resultの代わりに使うという方法が紹介されています。

ResultResult.swift
import Result

struct ResultResult<T, Error : ErrorType> {
    typealias Result = Result<T, Error>
}
import Alamofire
// import Result

typealias AnyResult = ResultResult<Any, NSError>.t

func someResult(value: Any) -> AnyResult {
    return .Success(value)
}

// もちろんfunc someResult(value: Any) -> ResultResult<Any, NSError>.t でも問題はないです

これで無事にResultのResultを明示的に指定してつかえるようになりました…!

png

追記(17' 03/14)

Swift3への対応をまとめてくださった方が!ありがとうございます。

早くswiftのバグ解消されないですかねえ…。

10
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?