2017-06-08 17 views
3

Swift 3.1からSwift 4コードベースの移行中に問題が発生しました。Swift 4:プロトコルを関連タイプとして実装した汎用プロトコルの実装

関連する型としてプロトコルを持つジェネリックパラメータでクロージャをとる汎用プロトコルメソッドを実装しようとすると、この問題が発生します。それは鳴るよりも簡単です:)

次のコードは、スウィフト3.1で正常に動作します:

protocol FooType { 
    associatedtype BarType 

    func foo(bar: BarType) 
    func foo(action: (BarType) -> Void) 
} 

protocol Bar {} 

class Foo: FooType { 
    typealias BarType = Bar 

    // Compiles in both 3.1 and 4 
    func foo(bar: Bar) { 
    } 

    // ERROR: Candidate has non-matching type (Bar) -> Void 
    func foo(action: (Bar) -> Void) {  
    } 
} 

しかしスウィフトに4コンパイラが私のクラスFoofoo(action:)メソッドの実装が欠落していると、プロトコルFooTypeに適合しない程度の誤差を与えます。

ところでXcode 9 "fix-it"は、私が持っているのと同じ実装を生成します。

パラメータタイプとしてBarTypeを使用するとコードがコンパイルされますが、具体的な型情報を緩和するのは好ましくありません。

答えて

3

typealias BarType = Bar 

行を削除しても問題が解決されることが判明します。公正なタイプの推論は、その仕事をしています。

しかし、それは法的なコードでなければならず、コンパイラのバグのようです。それに応じて

Reportedです。

0

typealias汎用変数を使用して、タイプを というプロトコルの関連タイプに指定する必要があります。私はfuntionでtypalias一般的な変数名を使用するために行くだろう。これはより理に適っていますが、私はまだコンパイラーがクロージャのtypealiasパラメーターを知らない理由を知りません。

class Foo: FooType { 
    typealias BarType = Bar 


    func foo(bar: BarType) { 
    /*Code*/ 
    } 


    func foo(action: (BarType) -> Void) { 
     /*Code*/ 
    } 
} 
+0

これは合法です。しかし、私たちはこの実装で作業している具体的な型について、コードの明確さを失っています。型推論は、すべてのプロトコル要件の実装が、それが動作している具体的な型を提供するならば、 'typealias'宣言を強制しないことによっても私たちを助けます。 関連付けられたタイプのセクションで[Appleの説明](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html)を確認できます。 – chezzdev

関連する問題