After the gloss project for Swift 4 in Xcode 9
I am getting following error which i have no idea
Closure tuple parameter '(key: _, value: _)' does not support destructuring
Code:
extension Dictionary
{
init(elements: [Element]) {
self.init()
for (key, value) in elements {
self[key] = value
}
}
func flatMap<KeyPrime, ValuePrime>(_ transform: (Key, Value) throws -> (KeyPrime, ValuePrime)?) rethrows -> [KeyPrime:ValuePrime] {
return Dictionary<KeyPrime, ValuePrime>(elements: try flatMap({ (key, value) in
return try transform(key, value)
}))
}
}
Error comes at this point try flatMap({ (key, value)in
It's a side-effect of this proposal for Swift 4:
SE-0110 Distinguish between single-tuple and multiple-argument function types.
But some features included in this proposal caused some regression which is addressed in this post of the evolution-announce mailing list:
[swift-evolution-announce] [Core team] Addressing the SE-0110 usability regression in Swift 4
So, you can expect in the future beta or GM version of Xcode 9, your code would compile well again. Until then, you can use this sort of workaround:
By the way, in Swift 4,
Dictionary
has some new initializers which takeSequence
of(Key, Value)
pair. For example:init(uniqueKeysWithValues: S)
Let's start with the definition of
flatMap
for a dictionary which is the following:You see that the
transform
closure takes only one parameter of typeElement
whereElement
is just atypealias
for a tuple:So the first and only argument of the closure should be a tuple of two elements (
key
of typeKey
andvalue
of typeValue
).Now, if you look at your code (which compiles in Swift 3), you will see that this is not the case, and you should be asking why does this even work in Swift 3.
Your closure takes 2 arguments instead of one (
key
of typeKey
andvalue
of typeValue
). This works in Swift 3 thanks to a feature called destructuring where the compiler will automatically transform a tuple of 2 elements into 2 arguments.But this feature is weird, rarely used and gives unexpected results most of the time so it has been removed in Swift 4.Edit: As pointed out by OOPer, this feature has been temporarily removed in Swift 4 beta but should be re-added before the final version is out.
Instead you should be writing:
And your
flatMap
function becomes:I just encountered this error as a result of using
enumerated().map()
:I typed the code:
And then kept pressing Enter until Xcode autocompleted the closure boilerplate.
The autocomplete seemingly has a bug that causes the above error. The autocomplete produces double-parenthesis
((offset: Int, element: String))
rather than single-parenthesis(offset: Int, element: String)
.I fixed it manually and was able to continue:
Possibly the result of using Xcode 10.0 beta (10L176w)