Swift返回带有泛型的结构

时间:2017-04-05 13:52:57

标签: swift generics struct

我在使用泛型时遇到了问题。

我有一个协议:SectionReusableView

public protocol SectionReusableView {

    associatedtype AdapterType: SectionReusableViewAdapter

    var adapter: AdapterType? { get set }

}

我有这个结构TableViewSectionReusableSupplementraryViewFactory

public struct TableViewSectionReusableSupplementraryViewFactory<T: SectionReusableView> {

    public var adapter: T.AdapterType

    public init(adapter: T.AdapterType) {

        self.adapter = adapter

    }

}

我想要的是创建一个函数,该函数将返回指定类型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>?'

1 个答案:

答案 0 :(得分: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(...)

最后一点,Swift是一种非常类型安全的语言。如果你希望允许你的工厂方法返回一个未知的专用类型,那么最好进一步抽象只返回一个原始协议。在这种情况下,您无需关心支持类型是什么。