2017-04-05 9 views
0

ジェネリック薬を使用している問題があります。ジェネリックのスウィフトリターン構造体

私は、プロトコル持っている:私は私が望むものをこの構造体にTableViewSectionReusableSupplementraryViewFactory

public struct TableViewSectionReusableSupplementraryViewFactory<T: SectionReusableView> { 

    public var adapter: T.AdapterType 

    public init(adapter: T.AdapterType) { 

     self.adapter = adapter 

    } 

} 

を持ってSectionReusableView

public protocol SectionReusableView { 

    associatedtype AdapterType: SectionReusableViewAdapter 

    var adapter: AdapterType? { get set } 

} 

どれTableViewSectionReusableSupplementraryViewFactory指定されたタイプT

のを返す関数を作成することです
func supplementaryViewFactory<T>(at index: Int, 
           within tableView: UITableView) -> TableViewSectionReusableSupplementraryViewFactory<T>? { 

    let adapter = self.adapter(at: index, within: tableView) 
    let reuseIdentifier = self.reuseIdentifier(at: index) 

    switch reuseIdentifier { 

    case AwesomeReusableView.AwesomeReusableViewReuseIdentifier: 

     guard let adapter = adapter as? AwesomeReusableViewAdapter else { return nil } 

     return TableViewSectionReusableSupplementraryViewFactory<AwesomeReusableView>(adapter: adapter) 

    default: 

     return nil 

    } 

} 

しかし、私はこのエラーを取得し、私は一般的な機能の使用方法ではありません

error: cannot convert return expression of type 
'TableViewSectionReusableSupplementraryViewFactory<AwesomeReusableView>' to return 
type 'TableViewSectionReusableSupplementraryViewFactory<T>?' 

答えて

0

を回避する方法がわかりません。

一般的な関数はTに特化しています。コンパイル時に新しい関数を作成して、さまざまな型で呼び出される特別な場合に使用します。

実際には、Tを使用してこの機能を特化しているわけではありません。あなたは未知のTと一致するかもしれないし、そうでないかもしれない明示的な戻り値型を与えています、コンパイラはそれを知らないのでそれを許可しません。

あなたがこれをlet factory = supplementaryViewFactory<FOO>(...)のように呼び出していたとしたら、実際にはTableViewSectionReusableSupplementraryViewFactory<BAR>を返します。 OOPSあなたはここで今

大きな問題を持って変換された例のようになります。注意すべき

func supplementaryViewFactory<T>(...) -> TableViewSectionReusableSupplementraryViewFactory<T>? where T: SectionReusableView { 

    let adapter = MyCoolAdapterClass() 

    guard let converted = adapter as? T.AdapterType else { return nil } 

    return TableViewSectionReusableSupplementraryViewFactory<T>(adapter: converted) 

} 

カップルの事、最初TableViewSectionReusableSupplementraryViewFactoryの種類が必要なタイプで専門ます。これが意味するのは、これが呼び出される型が、Tの内容を決定することになるということです。

あなたが何か持っている必要があるだろうので:

let factory : TableViewSectionReusableSupplementraryViewFactory<AwesomeReusableView>? = supplementaryViewFactory(...) 

最後の注意をあなたのファクトリメソッドが未知の専門的なタイプにそれを返すことができるように期待していた場合は、スウィフトは、非常にタイプセーフ言語うですおそらく生のプロトコルを返すだけに抽象化するのが最善でしょう。この場合、裏付タイプが何であるかを気にする必要はありません。

+0

ありがとう:)しかし、私はそれを好きではない、supplementaryViewFactoryを呼び出すクラスはどのタイプを特化するか分からない。 だから、私は "Any" TableViewSectionReusableSupplementaryViewFactory – Pwyll28

+0

@ Pwyll28を返そうと思っていたので、私は多くのことを考えました。その場合、ジェネリックスから遠ざかり、単純なジェーンプロトコルを使用することをお勧めします。または、ジェネリックを保持したい場合は、メイン構造体に、ファクトリメソッドの戻り値の型であるプロトコルを実装させ、をそれから削除してください – utahwithak

+0

しかし、このメソッドのポイントはのファクトリを返すことですまたはまたはを使用して、他のクラスのUITableViewDelegate/Datasourceメソッドを実装するためにファクトリを使用します@utahwithak – Pwyll28