我在使用泛型时遇到了问题。
我有一个协议: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>?'
答案 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是一种非常类型安全的语言。如果你希望允许你的工厂方法返回一个未知的专用类型,那么最好进一步抽象只返回一个原始协议。在这种情况下,您无需关心支持类型是什么。