我有一个代码(swift 4.2.1,xcode 10.1),给出了“冲突的一致性”编译错误。
应该如何重写它,做这种事情的最佳实践是什么?
代码应支持使用文本搜索来过滤字符串或复杂对象的数组...
protocol FilterableByText{
func filter<T: StringProtocol>(by text:T) -> Self
var isEmpty:Bool {get}
}
protocol ContainsString{
func contains<T>(_ substring: T) -> Bool where T : StringProtocol
}
extension Array: FilterableByText where Element:ContainsString{
func filter<T: StringProtocol>(by text:T) -> Array{
return filter{$0.contains(text)}
}
}
extension Array: FilterableByText where Element:FilterableByText{ // conflicting conformance
func filter<T: StringProtocol>(by text:T) -> Array{
return map{$0.filter(by: text)}.filter{!$0.isEmpty}
}
}
答案 0 :(得分:2)
代替尝试具有单独的一致性,您可以做的是创建具有不同约束的所需函数的单独实现。
protocol ContainsString {
func contains<T>(_ substring: T) -> Bool where T: StringProtocol
}
extension Collection {
func filter<T>(by text: T) -> [Element] where T: StringProtocol, Element: ContainsString {
return filter { $0.contains(text) }
}
func filter<T>(by text: T) -> [Element] where T: StringProtocol, Element: Collection, Element.Element: ContainsString {
return filter { !$0.filter(by: text).isEmpty }
}
}
extension String: ContainsString {}
let strings = ["hello", "world"]
strings.filter(by: "hello") // ["hello"]
let stringOfStrings = [strings, ["foo", "bar"]]
stringOfStrings.filter(by: "hello") // ["hello", "world"]
答案 1 :(得分:0)
如编译器所建议的,冲突的一致性是不可接受的-行为将是不确定的,因为在扩展中没有解决冲突函数签名的规则。对于最佳实践,我想说的是为元素引入更多通用的但单一的协议,因此不会使您在默认扩展名中拆分逻辑: