如何解决面临协议关联类型的问题
我有一个 tableview 视图数据列表,用户可以在其中选择一个我使用 ZPPickerDataSource 协议作为数据源的项目,现阶段没有问题
public protocol ZPPickerDataSource: ZPSearchableDataSource {
var uuID: String {get}
var displayString: String {get}
}
此外,UI 还具有搜索功能,为此我使用了 ZPSearchableDataSource、ZPSearchable。 ZPPickerDataSource 协议向 ZPSearchableDataSource 确认。
public protocol ZPSearchableDataSource {
var displayString: String {get}
}
public protocol ZPSearchable {
associatedtype dataSourceType: ZPSearchableDataSource
var searchableItems: [dataSourceType] {get}
func search(keyword: String) -> [dataSourceType]
}
public extension ZPSearchable {
func search(keyword: String) -> [dataSourceType] {
return searchableItems.filter{$0.displayString.contains(keyword)}
}
}
当我提到 ZPSearchable 协议的
typealias dataSourceType = ZPPickerDataSource
我收到类似您的控制器未确认协议 ZPSearchable 之类的错误。
class MyPickerScreen: ZPSearchable {
typealias dataSourceType = ZPPickerDataSource
var searchableItems: [dataSourceType] {
return []
}
var searchResults: [dataSourceType] = []
func searchItem(namedLike searchQuery: String) {
searchResults = search(keyword: searchQuery)
}
}
附: 我试过名为 TestSource 的结构作为数据源。我提到
typealias dataSourceType = TestSource
然后代码编译。似乎它只发生在协议中。
public struct TestSource: ZPPickerDataSource {
public var uuID: String = ""
public var displayString: String = ""
public var sampleVar = ""
}
解决方法
令人惊讶的是,ZPPickerDataSource
不符合 ZPSearchableDataSource
。只有具体类型符合协议。协议不符合协议。请参阅 this post 中 Hamish 的回答以了解原因。
因此,您的类型别名:
typealias dataSourceType = ZPPickerDataSource
不满足dataSourceType
必须符合ZPSearchableDataSource
的约束,所以不满足关联类型要求,所以你的类型不符合协议ZPSearchable
。
您必须为关联类型使用结构/类。您似乎希望能够使用 any ZPPickerDataSource
。在这种情况下,您可以编写一个符合 ZPPickerDataSource
的结构,并编写一个将任何 ZPPickerDataSource
转换为您的结构的函数:
struct AnyZPPickerDataSource: ZPPickerDataSource {
let wrapped: ZPPickerDataSource
var uuID: String { wrapped.uuID }
var displayString: String { wrapped.displayString }
init(_ dataSource: ZPPickerDataSource) {
wrapped = dataSource
}
}
然后你可以这样做:
class MyPickerScreen: ZPSearchable {
var searchableItems: [AnyZPPickerDataSource] = []
typealias dataSourceType = AnyZPPickerDataSource
}
现在您可以将任何类型的 ZPPickerDataSource
放入 searchableItems
,例如
searchableItems.append(AnyZPPickerDataSource(TestSource(...)))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。