2017-07-06 84 views
9

在Xcode 9关闭元组不支持解构在Xcode9 Swift4

为Swift4光泽项目

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

闭幕元组参数“(键后:_,值:__)”不支持 解构

代码:

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

+0

'Dictionary.init(元素:)'不能迅标准库中找到。你自己定义它? – OOPer

+0

是的,我正在更新答案 –

+0

我已更新答案 –

回答

9

让我们先从一个词典中的flatMap定义,如下:

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

你看到transform关闭仅需一种类型的参数Element其中Element只是一个元组的typealias

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

所以第和仅封闭的参数应该是两个元件(Key类型的keyvalueValue类型)的一个元组。现在


,如果你看看你的代码(编译斯威夫特3),你会看到,这是不是这种情况,你应该问为什么这甚至在斯威夫特3.

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

你的闭合需要两个参数,而不是一个(keyKey类型和Value类型的value)。这可以在Swift 3中使用,这要归功于一个名为解构的功能,其中编译器会自动将2个元素的元组转换为2个参数。

但是这个功能是怪异,很少使用,所以它在斯威夫特被删除4.
编辑给出了意外的结果大部分的时间:由于OOPer指出,此功能已暂时去掉Swift 4测试版,但应在最终版本发布之前重新添加。

相反,你应该写:

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

感谢您的解释。这是我试图与swift4兼容的第三方库。 –

3

这是该提案的雨燕为4副作用:

​​。

但对此提案中包含的一些功能引起了一些回归这是在这个职位evolution-announce mailing list的解决:

[swift-evolution-announce] [Core team] Addressing the SE-0110 usability regression in Swift 4

所以,你可以在Xcode9未来测试或GM版本期待,你的代码会再次编译好。在那之前,你可以使用这种解决办法的:

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

顺便说一句,在斯威夫特4,Dictionary具有采取(Key, Value)Sequence一些新的初始化。例如:

init(uniqueKeysWithValues: S)