2017-07-06 86 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)