2017-01-12 10 views
2

私はSwift 3を使用しています。私のバックエンドは、様々な方法で応答をページングするさまざまなコンテンツタイプに対して、いくつかの異なるエンドポイントを持っています。すべてのコンテンツタイプに対して実装できる汎用プロトコルを作成しようとしています。そのプロトコルに準拠したクラスの宣言でプロトコル関数の戻り値型を指定する

protocol DynamicContentFetcher { 
    func content() -> MutableObservableArray<Any> 
    func getNext() 
    func refresh() 
} 

これらのインスタンスの1つはAdSearchです。

class AdSearch: DynamicContentFetcher { 
    var results = MutableObservableArray<DynamicAd>([]) 
    func content() -> MutableObservableArray<Any> { 
     return results 
    } 

returnことは理にかなってエラーCannot convert return expression of type MutableObservableArray<DynamicAd> to return type 'MutableObservableArray<Any>、とコンパイルされません。私はAdSearch<DynamicAd>ようDynamicContentFetcherに準拠した私のクラスを初期化し、プロトコルにfunc content() -> MutableObservableArray<#Specified Type#>を行うには> <にその値を使用することができればいいだろう何

でした。これはSwiftでも可能ですか?

MutableObservableArrayは、反応性プログラミングポッドであるBondフレームワークのクラスです。

+0

ジェネリックスはSwiftでは共変ではありません。それはエラーの原因です: 'MOA 'は 'MOA 'のサブタイプではありません。型パラメータを明示的にします(dfriの答えに示されているように)。 (悪いタイトルを選んだ、それはあなたの質問については何も教えてくれません) – Raphael

+0

@Raphaelタイトルは申し訳ありません、英語は私の母国語ではなく、私が達成しようとしていたことを説明するのは難しかったです。 –

答えて

5

あなたのプロトコルでassociatedtypeを使用して、あなたのプロトコルでcontent()の戻り値の型にtypeholderとしてこれを使用することができます。

struct MutableObservableArray<T> {} 

protocol DynamicContentFetcher { 
    associatedtype T 
    func content() -> MutableObservableArray<T> 
    //func getNext() 
    //func refresh() 
} 

struct DynamicAd {} 

class AdSearch: DynamicContentFetcher { 
    var results = MutableObservableArray<DynamicAd>() 
    func content() -> MutableObservableArray<DynamicAd> { 
     return results 
    } 
} 

いいだろう何を、私はできればしました私のクラスは DynamicContentFetcherのようにAdSearch<DynamicAd>のようになり、その値を <>に入れてfunc content() -> MutableObservableArray<#Specified Type#>を というプロトコルで使用してください。

あなたは(暗黙的推論により、下記)を指定するために使用される一般的なtypeholder DynamicContentFetcherプロトコルのassociatedtypeためtypealiasを保持し、AdSeachクラスは、一般的なこと聞かせしたい場合があります。

class AdSearch<U>: DynamicContentFetcher { 
    // typealias T = U // infered 
    var results = MutableObservableArray<U>() 
    func content() -> MutableObservableArray<U> { 
     return results 
    } 
} 

struct DynamicAd {} 
let dynamicAdSearch = AdSearch<DynamicAd>() 
+0

ありがとう!タイプを指定せずに定義できるようにすることは可能ですか? AdSearchを定義するモデルでは、 'var contentFetcher:DynamicContentFetcher 'を持っていますが、これは私に "プロトコルは自己またはタイプ要件があるためジェネリックインクルードとしてのみ使用できます"私が指定していない場合、または "非ジェネリック型を特化できない"という場合は、指定します。 –

+1

Swiftコンパイラが 'AdSearch'が' T'にどのような型を使うかは分かりますが、 'typalias T = DynamicAd'を追加すると分かりやすくなると思います。 – Raphael

+0

@OscarApeland次のように宣言することができます: 'func contentFetcher () - > U where U.T:DynamicContent {...}'戻り値をインスタンス化する方法はわかりません。 :D – Raphael

関連する問題