противоречивое соответствие протоколу - лучшие практики - PullRequest
0 голосов
/ 15 марта 2019

У меня есть код (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}
    }
}

Ответы [ 2 ]

2 голосов
/ 15 марта 2019

Вместо того, чтобы пытаться иметь отдельные соответствия, вы можете создать отдельные реализации желаемой функции с различными ограничениями.

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"]
0 голосов
/ 15 марта 2019

Как предполагает компилятор, конфликтующее соответствие недопустимо - поведение будет неопределенным, так как нет никаких правил для разрешения сигнатур конфликтующих функций в расширениях. Для лучшей практики, я бы сказал, введите более общий, но единый протокол для элементов, чтобы он не заставлял вас разделять логику в расширении по умолчанию:

...