2016-09-26 3 views
0

私はSwift 2から自分のコードを移行しようとしているので、私は(Xcode 8、Swift 3)を理解できません。タプルとは関係がありますが、私は完全にはわかりません。Swift 3:ネストされた汎用タイプ

私はいくつかのジェネリックスを定義するジェネリッククラスを持っています。これらのジェネリック医薬品では、私もカップル型の別名のセットアップおよびそれらを使用する関数持っている:割り当て(let pendingRequest: Request = ...)で

open class GuardPool <Key: Hashable, Resource> { 

    public typealias ResourceCallback = ([Resource]) -> Void 
    public typealias Request = (keys: Set<Key>, cb: ResourceCallback) 
    fileprivate var pendingRequests: [Request] = [] 

    open func request(_ keys: Set<Key>, cb: ([Resource]) -> Void) { 
    let pendingRequest: Request = (keys: keys, cb: cb) 
    pendingRequests.append(pendingRequest) 
    } 
} 

を、私はこのエラーを取得する:

Cannot convert value of type 'Set<Key>' to specified type 'Set<_>' 

私は理解できませんこれを修正する方法を説明します。コンパイラがSetの型情報を認識できないようです。

注:明らかに、クラスはこれよりもはるかに大きいです。 300行を挿入するのではなく、関連するコードをコピーして貼り付けました。

答えて

0

エラーメッセージは誤解を招く可能性があります。 のでcbパラメータ@escapingとしてマークする必要があります:あなたは 2行目の(不要)明示的な型注釈

let pendingRequest = (keys: keys, cb: cb) 

を削除した場合、コンパイラは、実際の問題が明らかになった

 
error: non-escaping parameter 'cb' may only be called 
note: parameter 'cb' is implicitly non-escaping 

と述べていますそれはプロパティに格納され、requestメソッドから返された後、 の後で呼び出されることがあります。

open func request(_ keys: Set<Key>, cb: @escaping ([Resource]) -> Void) { 
    let pendingRequest = (keys: keys, cb: cb) 
    pendingRequests.append(pendingRequest) 
} 

Swift 2では、クロージャがデフォルトでエスケープされ、 と@noescapeとマークすることができました。 Swift 3では、クロージャはデフォルトではエスケープされません。 はSE-0103: Make non-escaping closures the defaultです。

+0

これは非常に誤解を招くエラーメッセージでした。私はちょうどそれを考え出し、自分の質問に答えるつもりでしたが、あなたは私にそれを打つ!ありがとう! –

+0

40kを超えるコード行が処理されるため、移行担当者はクロージャーに「@エスケープ」マークを付ける必要がある場所を逃しました。明示的な割り当ては、私がこの 'pendingRequests.append((keys:keys、cb:cb))でエラーを出したために行われました。私は、明示的に型付けされた課題を追加することで問題を解決したいと考えていましたが、同じエラーが発生し続けました。面白いことに、この同じエラーは、ネストされた型とクロージャがタプルで結合されたコードのいくつかの場所で発生しています。 –

関連する問題