如何在Swift中为Collection添加支持Entity协议的泛型约束扩展?
泛化Swift集合的搜索方法以支持所有遵循Entity协议的类型
背景
我有一个遵循Entity协议的Profile类,目前给所有元素为Profile的Swift集合扩展了一个搜索方法。但我想把这个方法泛化,让它不仅支持Profile,还能支持所有遵循Entity协议的对象。
原代码
protocol Entity { var name: String { get } } class Profile: Entity { ... } extension Collection where Element == Profile { func searched(with search: String) -> [Profile] { guard !(search.isEmpty) else { return self } return self.filter { ($0.name.lowercased().contains(search.lowercased())) } } }
问题
如何让这个搜索方法泛化,以支持所有遵循Entity协议的对象?
解决方案
只需要修改集合扩展的约束条件,将Element == Profile替换为Element: Entity,同时调整返回类型为[Element],就能让这个方法支持所有遵循Entity协议的元素类型。修改后的代码如下:
protocol Entity { var name: String { get } } class Profile: Entity { ... } extension Collection where Element: Entity { func searched(with search: String) -> [Element] { guard !search.isEmpty else { return Array(self) } let lowercasedSearch = search.lowercased() return filter { $0.name.lowercased().contains(lowercasedSearch) } } }
说明
- 约束改为
Element: Entity:表示只要集合的元素遵循Entity协议,就可以调用这个搜索方法,不再局限于Profile类型。 - 返回类型调整为
[Element]:保证返回的数组元素类型和原集合的元素类型一致,避免类型转换问题。 - 额外优化:提前将搜索字符串转为小写,避免在
filter的闭包中重复执行转换操作,提升代码效率。
内容的提问来源于stack exchange,提问作者christophriepe
相关产品推荐
相关产品推荐

