2015-12-02 75 views
2

據我瞭解,雨燕的map功能執行以下操作:斯威夫特的映射函數

  • 在任何採用SequenceType
  • 想法是返回另一個「東西」工程(尋找一個更好的詞),其有它是通過你傳遞到封閉的邏輯轉化元素
  • 始終返回「東西」仍然符合SequenceType和元素#不改變

例如:

我們有2類牛奶奶酪。我們給出的構造函數奶酪,這是這樣的:

init(withMilk milk: Milk) { 
    self.milk = milk 
} 

鑑於牛奶對象的數組,我們把奶陣列對象爲奶酪對象,像這樣:

let arrayOfCheese = arrayOfMilk.map { Cheese(withMilk: $0) } 

這對我來說很好。但現在我想要比普通奶酪更多的東西。我需要的成分來自全國各地的地方:

let arrayOfSuperCheese = arrayOfMilk.map { 
    let cheese = Cheese(usingMilk: $0) 
    let sulfur = Sulfur() 
    let minerals = Minerals() 
    let mixer = Mixer() 

    let superCheese = mixer.mixIn(sulphur: sulphur, minerals: minerals) 
    return superCheese 
} 

編譯器告訴我:

Cannot invoke 'map' with an argument list of type '(@noescape (Element) throws -> _)

上面的例子大致是我目前遇到的問題。請讓我知道這個例子是否有意義。

+0

你的代碼示例使用'withMilk',但用法使用'usingMilk'。你確定你的代碼沒有錯字嗎? –

+0

固定,對不起。我實際上沒有這樣的代碼,只是把它放在了我的問題的背景下。 –

回答

2

這是非常複雜的,它不能合理地推斷閉包簽名。因此請指定它:

let arrayOfSuperCheese = arrayOfMilk.map { (milk: Milk) -> Cheese in 
    let cheese = Cheese(usingMilk: milk) 
    let sulfur = Sulfur() 
    let minerals = Minerals() 
    let mixer = Mixer() 

    let superCheese = mixer.mixIn(sulfur: sulfur, minerals: minerals) 
    return superCheese 
} 
+0

顯然,這個閉包中的'cheese'常量沒有被使用,但我想盡可能地保留你的代碼片段。另外,根據以下常見約定,我不會使用'useMilk'(或'withMilk',您在其他地方參考)第一個參數「Cheese」,而不是'milk',但這取決於您。 – Rob

+0

感謝您的回答和建議。只要我明確定義了結束簽名,它就會工作。您是否知道何時需要明確的結束簽名? –

+0

不,我不知道確切的閾值,但它的例子比這個簡單得多。例如。 '讓奶酪=牛奶。地圖{讓奶酪=奶酪(牛奶:$ 0);返回芝士}'。有一些行爲會隨着多行封閉而改變,所以也許就是這樣,但我懷疑它可能比這更微妙。底線,我用推斷的類型編寫代碼,直到編譯器告訴我它不能再推斷爲止,然後我明確指定參數。 – Rob