封闭元组不支持在Xcode9 Swift4中解构

在Xcode 9中的Swift4的光泽项目之后

我得到以下错误,我不知道

封闭元组参数'(key:_,value:_)'不支持解构

码:

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) })) } } 

此时try flatMap({ (key, value)in

让我们从flatMap的定义开始,如下所示:

 func flatMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] 

您会看到, transform闭包只接受一个types为Element 参数 ,其中Element只是元组的一个typealias

 public typealias Element = (key: Key, value: Value) 

所以闭包的第一个也是唯一的参数应该是两个元素的元组( keytypes的KeyValuetypes的Value )。


现在,如果你看看你的代码(在Swift 3中编译的代码),你会发现情况并非如此,你应该问为什么在Swift 3中工作。

 try flatMap({ (key, value) in return try transform(key, value) }) 

你的闭包需要2个参数而不是1个( keytypes的KeyValuetypes的Value )。 这在Swift 3中有效,这要归功于一个称为解构的特性,编译器会自动将2个元素的元组转换为2个参数。

但是这个function很奇怪,很less使用,并且在大多数情况下会产生意想不到的结果,所以在Swift 4中它已经被删除了。
编辑 :正如OOPer指出的,这个function已经在Swift 4testing版中暂时删除了,但在最终版本发布之前应该重新添加。

相反,你应该写:

 try flatMap({ tupleArgument in return try transform(tupleArgument.key, tupleArgument.value) }) 

而你的flatMap函数变成:

 func flatMap<KeyPrime, ValuePrime>(_ transform: (Key, Value) throws -> (KeyPrime, ValuePrime)?) rethrows -> [KeyPrime:ValuePrime] { return Dictionary<KeyPrime, ValuePrime>(elements: try flatMap({ element in return try transform(element.key, element.value) })) } 

这是斯威夫特4提出的一个副作用:

SE-0110区分单元组和多个参数的函数types 。

但是这个提议中包含的一些function导致了这个演变通告邮件列表的这个post中的一些回退

[swift-evolution-announce] [核心团队]在Swift 4中解决SE-0110可用性回归问题

所以,你可以期待在未来的testing版或通用版Xcode9中,你的代码会再次编译好。 在此之前,您可以使用这种解决方法:

 internal func flatMap<KeyPrime , ValuePrime>(_ transform: (Key, Value) throws -> (KeyPrime, ValuePrime)?) rethrows -> [KeyPrime : ValuePrime] { return Dictionary<KeyPrime,ValuePrime>(elements: try flatMap({ pair in let (key, value) = pair return try transform(key, value) })) } 

顺便说一下,在Swift 4中, Dictionary有一些新的初始化方法,它们是(Key, Value)对的Sequence 。 例如:

init(uniqueKeysWithValues:S)