Неоднозначный вызов функции расширения коллекции - PullRequest
0 голосов
/ 13 сентября 2018

Компилятор говорит мне, что

Expression type '([String]) -> Bool' is ambiguous without more context

Я не уверен, как добавить больше контекста к заявлению. Я думал, что объявление Extension сообщит функции все, что ей нужно, об элементах в коллекции. Я оставил больше мыслей во фрагменте кода. Найдите область с пометкой "!!! COMPILE ERROR !!!"

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

protocol Measurement {
    var id: String { get }
    var displayPriority: Int { get }
}

extension Collection where Element: Collection, Element.Element: Measurement {
    func contains(ids: [String]) -> Bool {
        return self.filter{ measurementCollection -> Bool in
            // !!! COMPILE ERROR !!!
            // Error: Expression type '([String]) -> Bool' is ambiguous without more context
            //
            // The compiler doesn't under stand that this is a collection of Measurement,
            // Do I somehow need to tell the compiler that the elements to the collection 
            // or collections with elements with a type that is a kind of Measurement again?
            // I thought the extension declaration already specified everything it needed.
            return measurementCollection.isEquals(ids: ids)
        }.count > 0
    }
}


extension Collection where Element == Measurement {
    func isEquals(ids: [String]) -> Bool {
        // get all the IDs
        let allIDs = self.map{ $0.id }

        // convert it to a set to make comparisons easier
        return Set(allIDs) == Set(ids)
    }
}

func whatIwantToDo() {
    let measurements = [[ConcreteMeasurement("A")],
                        [ConcreteMeasurement("B")],
                        [ConcreteMeasurement("C"), ConcreteMeasurement("D")]
    ]

    let ids = ["C", "D"]
    // Ultimately, I want to fix my compile error to run the following line of code, this should output to True
    print("Does measurements contain: \(ids) -> \(measurements.contains(ids: ids))" )
}

1 Ответ

0 голосов
/ 13 сентября 2018

Первое расширение имеет ограничение Element.Element: Measurement, что означает, что в замыкании measurementCollection является коллекцией, типы элементов которой принимают протокол Measurement.

Следовательно,чтобы вызвать метод isEquals() из второго расширения этой коллекции, его необходимо определить как

extension Collection where Element: Measurement { // Not: Element == Measurement
    func isEquals(ids: [String]) -> Bool { ... }
}

. Обратите внимание также, что обычно тест

filter { ... }.count > 0

более эффективенсделано как

contains(where: { ... })
...