7
votes

Is this a bug in Swift 3 compiler? It's not ambiguous, it's == and two Strings.

It says:

error: ambiguous reference to member '=='
let strs = things.filter { return $0.id == "1" } .map { t in
                                        ^~

For this example code:

class Thing {
    var id: String = ""
}
let things = [Thing]()
let x = 1
let strs = things.filter { return $0.id == "1" } .map { t in
    if x == 1 {
        return "a"
    }
    else {
        return "b"
    }
}
2

2 Answers

10
votes

It's a misleading error message – the ambiguity actually lies with the closure expression you're passing to map(_:), as Swift cannot infer the return type of a multi-line closure without any external context.

So you could make the closure a single line using the ternary conditional operator:

let strs = things.filter { $0.id == "1"} .map { _ in
    (x == 1) ? "a" : "b"
}

Or simply supply the compiler some explicit type information about what map(_:) is returning:

let strs = things.filter { $0.id == "1"} .map { _ -> String in

let strs : [String] = things.filter { $0.id == "1"} .map { _ in
0
votes

I've just had a similar issue where the < operator was marked as ambiguous when trying to use my own filter function:

let shortNames = names.myFilter { (name) -> Bool in
    return name.count < 4
}

Similarly to the answer from @Hamish I fixed this by explicitly setting the type of name:

(name: String)

I shouldn't have to do this of course but it works.