对集合扩展功能的歧义调用 [英] Ambiguous call to Collection extension function

查看:100
本文介绍了对集合扩展功能的歧义调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编译器告诉我

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

我不确定如何在语句中添加更多上下文.我以为扩展声明会告诉函数它所需的有关集合中元素的所有信息.我在代码片段中留下了更多的想法.查找标记为"!!! COMPILE ERROR !!!"的区域

I'm not sure how to add more context to the statement. I thought the Extension declaration would have told the function everything it needed about the elements in the collection. I've left more thoughts in the code snippet. Look for the area marked "!!! COMPILE ERROR !!!"

您应该能够将代码复制并粘贴到一个空项目中,以查看编译错误.

You should be able to copy and paste the code into an empty project to see the 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))" )
}

推荐答案

第一个扩展名具有约束Element.Element: Measurement, 这意味着在闭包中,measurementCollection是一个集合,其 元素类型采用 Measurement协议.

The first extension has the constraint Element.Element: Measurement, which means that in the closure, measurementCollection is a collection whose element types adopts the Measurement protocol.

因此,为了从此集合的第二个扩展中调用isEquals()方法,必须将其定义为

Therefore, in order to call the isEquals() method from the second extension on this collection, it must be defined as

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

还请注意,通常是测试

filter { ... }.count > 0

的执行效率更高

contains(where: { ... })

这篇关于对集合扩展功能的歧义调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆