2016-05-05 2 views
0

誰かがこれがうまくいかない理由を私に説明することはできますか?汎用パラメータTを推測できませんでした。工場の方法

私はこのようなファクトリメソッドを持つクラスをしている:次に、喜んでそれをコンパイルすることを知った後、私はこのようなタスクを作成するために行く

public class NetworkTask<T> { 

    var request: URLRequest 

    var completionHandler: NetworkResponse<T> -> Void 

    init(request: URLRequest, completionHandler: NetworkResponse<T> -> Void) { 

     self.request = request 
     self.completionHandler = completionHandler 
    } 

    static func dataResponseTaskWithRequest(request: URLRequest, completionHandler: NetworkResponse<NSData> -> Void) -> NetworkTask<NSData> { 

     return NetworkTask<NSData>(request: request, completionHandler: completionHandler) 
    } 

    static func mappedObjectResponseTaskWithRequest<MappedType>(request: URLRequest, completionHandler: NetworkResponse<MappedType> -> Void) -> NetworkTask<MappedType> { 

     return NetworkTask<MappedType>(request: request, completionHandler: completionHandler) 
    } 
} 

let task = NetworkTask.dataResponseTaskWithRequest(URLRequest()) { (response) in 

    } 

いや...

ジェネリックパラメータTを推測することができませんでした

私がはっきりと推測できるので、メソッドはNetworkTask<NSData>を返します。したがってTはNSDataです。

[OK]を...次に、このようなのでしょうか?

let task: NetworkTask<NSData> = NetworkTask.dataResponseTaskWithRequest(URLRequest()) { (response) in 

} 

いや...

タイプの引数リストで 'dataResponseTaskWithRequest' '(URLRequestの、(_) - > _')を呼び出すことはできませんので、多分、

[OK]を他の方法:

let task = NetworkTask.mappedObjectResponseTaskWithRequest(URLRequest()) { (response: NetworkResponse<String>) in 

} 

いや...

0予想 引数の型へ -

型の値に変換できません '>()(NetworkResponseを)' 'NetworkResponse < _> - >ボイド'

コンパイラは「可能性があるため、私は明らかにここで何かが欠けする必要があります非常に多くのエラーがあります。誰か手掛かりがありますか?

答えて

3

NetworkTask<T>は、NetworkTaskではなくタイプです。つまり、パラメータTがクラスにあり、そのクラスでやっているすべてのこと、クラスメソッドにアクセスするためには、その型の説明が必要です。この方法は、すべての上にあることを代わりに想像 - Tがあなたのコンパイルエラーを与えるメソッド宣言に含まれていないにもかかわらず

は、型パラメータが含まれていないすべてのクラスメソッドを含んでいるでしょう何のクラスNetworkTaskはありませんクラスNetworkTask<T>の値はTです。これはC++に似ています。対応するものは「テンプレート」と呼ばれます。つまり、ジェネリック型のパラメータを持つクラス宣言は、異なるクラスを文字通りコンパイルするためのテンプレートとして使用されます。これは、ジェネリックスの構文がタイプイレーズのコンパイル時の砂糖(実際にはクラスメソッドを呼び出すことができます - この場合、実際には1つのクラスのみが存在します)のJavaとは異なります。

は、ここでは、このいくつかのより多くのデモするために、最小限の例です:

A<IntegerLiteralType>.foo()

あなたはおそらく、検討する必要があります。上記の例の場合

class A<T> { 
    class func foo() { 
    } 

    class func bar(t:T) -> Void { 
    } 
} 

class B {} 

A.foo() // this gives an error because the type cannot be inferred. 

A.bar(1) // this works fine without compiler errors as the integer literal type can be inferred there. 

を、Aは、とインスタンスのために呼び出さする罰金だろうこの場合のメソッドがその型パラメータTを持つクラスに属しているのか、それとも受信者として何か他のものを持つべきかどうか(実際には自由な関数であるべきかどうか)

+0

これは間違いありません。私の場合、それはポイントを打つので、私は静的メソッドを持つTaskBuilderクラスを作成しました。このアプローチはうまくいくようです。ご回答どうもありがとうございました。 – diegomontoyas

関連する問題