关闭元组不支持Xcode 9 Swift 4中的解构

在Xcode 9中为Swift 4进行光泽项目之后

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

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

码:

extension Dictionary { init(elements: [Element]) { self.init() for (key, value) in elements { self[key] = value } } func flatMap(_ transform: (Key, Value) throws -> (KeyPrime, ValuePrime)?) rethrows -> [KeyPrime:ValuePrime] { return Dictionary(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闭包只接受Element类型的一个参数 ,其中Element只是元组的一个typealias

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

所以闭包的第一个也是唯一的参数应该是两个元素的元组( key类型的KeyValue类型的Value )。


现在,如果你查看你的代码(在Swift 3中编译),你会发现情况并非如此,你应该问为什么这甚至可以在Swift 3中运行。

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

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

但是这个function很奇怪,很少使用,并且大部分时间都会产生意想不到的结果,因此它已经在Swift 4中删除了。
编辑 :正如OOPer所指出的,此function已在Swift 4测试版中暂时删除,但应在最终版本发布之前重新添加。

相反,你应该写:

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

你的flatMap函数变成:

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

这是Swift 4提案的副作用:

SE-0110区分单元组和多元函数类型 。

但是这个提案中包含的一些function引起了一些回归 ,这篇文章在evolution-announce邮件列表的这篇文章中得到了解决:

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

因此,您可以预期在未来的Xcode 9的beta或GM版本中,您的代码将再次编译良好。 在此之前,您可以使用这种解决方法:

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

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

init(uniqueKeysWithValues:S)

我刚刚使用enumerated().map()遇到了这个错误:

Closure元组参数不支持解构

我输入了代码:

 ["foo"].enumerated().map( 

然后按住Enter直到Xcode自动完成闭包样板。

自动完成似乎有一个导致上述错误的错误。 自动完成生成双括号((offset: Int, element: String))而不是单括号(offset: Int, element: String)

我手动修复它并且能够继续:

 // Xcode autocomplete suggests: let fail = ["foo"].enumerated().map { ((offset: Int, element: String)) -> String in return "ERROR: Closure tuple parameter does not support destructuring" } // Works if you manually replace the "(( _ ))" with "( _ )" let pass = ["foo"].enumerated().map { (offset: Int, element: String) -> String in return "works" } 

可能是使用Xcode 10.0 beta(10L176w)的结果