问题
The following code compiles in Swift 3
extension Array where Element: Equatable {
var removeDuplicate: [Element] {
return reduce([]){ $0.0.contains($0.1) ? $0.0 : $0.0 + [$0.1] }
}
}
but produces the error
error: contextual closure type '(_, _) -> _' expects 2 arguments, but 1 was used in closure body
in Swift 4. How to convert this code to be compiled in Swift 4?
回答1:
The closure passed to reduce
takes 2 parameters, e.g. $0
and $1
in the shorthand notation:
extension Array where Element: Equatable {
var removeDuplicate: [Element] {
return reduce([]) { $0.contains($1) ? $0 : $0 + [$1] }
}
}
(This compiles in both Swift 3 and 4.)
In Swift 3 you could use single parameter $0
, which would the be inferred as a tuple with elements $0.0
and $0.1
.
This is not possible anymore in Swift 4, as a consequence of SE-0110 Distinguish between single-tuple and multiple-argument function types.
Here is another example demonstrating the change: This
let clo1: (Int, Int) -> Int = { (x, y) in x + y }
let clo2: ((Int, Int)) -> Int = { z in z.0 + z.1 }
both compiles in Swift 3 and 4, but this
let clo3: (Int, Int) -> Int = { z in z.0 + z.1 }
compiles only in Swift 3, not in Swift 4.
来源:https://stackoverflow.com/questions/46432013/contextual-closure-type-expects-2-arguments-error-when-using-reduce-in-swift-4