2016-06-24 30 views
-1

使用Xcode 8測試版,swift 3不能編譯第二個擴展。我不明白這是一個很快的bug還是一個已知的限制。 (Element,T) - > T的確是函數的類型。 所以我不明白爲什麼編譯器期望() - > __ ,什麼是這種類型的意思是旁邊「我不關心型」爲什麼Swift類型的系統嘗試將類型轉換爲錯誤的預期參數

+0

我不鼓勵在這裏使用遞歸,因爲它會複製每個調用的整個數組,導致'O(n^2)'的時間複雜度。你只需使用for循環即可。 –

回答

1

這是不是一個錯誤或限制,它只是編譯器不可能在編譯時確定first在第二個擴展中的類型爲T(因爲T不一定與Iterator.Element相同)。在你的關閉中,編譯器知道first的類型爲Iterator.Element,但編譯器無法知道這是否也是類型T

在您的第一個擴展中,您只使用first作爲combine閉包的第一個參數,因爲它只需要Iterator.Element類型,所以一切都很好。

在你的第二個延伸,但是,你試圖傳遞first作爲參數傳遞給它期望類型T參數(initial),編譯器無法知道first是否真的是T型(同一類型T的13759 combine閉包用於呼叫雙參數scanl),即Iterator.Elementself的類型爲T。這可以通過firstT的嘗試類型轉換(as?)在第二個擴展的可選綁定條款中輕易兌換。

extension Array { 
    func scanl<T>(combine: (Iterator.Element, T) -> T) -> [T] { 
     guard let first = self.first as? T else { return [] } 
     return Array(self.dropFirst()).scanl(initial: first, combine: combine) 
    } 
} 

如果構建一個掃描類型的數組來構造另一種類型,例如陣列的例子Iterator.ElementT不一定是相同類型的事實是明顯的

/* scant [Int] array to construct [String] array */ 
let foo = [1, 2, 3, 4, 5] 
let bar = foo.scanl(initial: "0") { String($0) + $1 } 
print(bar) // ["0", "10", "210", "3210", ""] 

如果你只喜歡你scanl方法,其集電極產生相同類型的數組(作爲一個被掃描),那麼你就不需要包括通用T,但可以使用到位Iterator.Element類型T在你的分機上面。

相關問題