2016-06-24 14 views
-1

Xcode 8 betaを使用すると、2番目の拡張子はコンパイルできません。これが迅速なバグか既知の制限であるかどうかはわかりません。Swiftタイプのシステムがタイプを間違った期待パラメータに変換しようとしています

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


extension Array { 
    func scanl<T>(combine: (Iterator.Element, T) -> T) -> [T] { 
     guard let first = self.first else { return [] } 
     return Array(self.dropFirst()).scanl(initial:first, combine:combine)// Cannot convert value of type '(Element, T) -> T' To expected argument type '(_, _) -> _' 
    } 
} 

(要素、T) - > Tは実際に関数の型です。 ので、コンパイラは()期待する理由を私は理解できない - これはバグや制限はない

+0

私はここで再帰を使うことをお勧めしません。なぜなら、それぞれの呼び出し全体をコピーし、 'O(n^2)'という時間の複雑さにつながるからです。 'for'ループを使うだけで良いでしょう。 –

答えて

1

を > __と、このタイプは、「私は種類を気にしない」の横に何を意味している、それは単にですコンパイラがコンパイル時にfirstのタイプがTであることを確認することは不可能です(Tは必ずしもIterator.Elementと同じである必要はありません)。どちらのクロージャでも、コンパイラはfirstがタイプIterator.Elementであることを知っていますが、コンパイラはこれもタイプTであるかどうかを知ることができません。

最初の拡張では、combineクロージャの最初の引数としてfirstを使用します。これはタイプがIterator.Elementであるため、すべてが良好です。あなたの第二延長で

、しかし、あなたはTを入力見込んパラメータ(initial)に引数としてfirstを渡そうとすると、コンパイラがで使用されるようfirstが本当にタイプT(同じタイプTであるかどうかを知ることができませんscanlを呼び出すために使用されたcombineクロージャ)、つまりIterator.Elementselfの場合はTです。これは、この第2の拡張のオプションの拘束節において、firstからTの試みられたタイプ変換(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) 
    } 
} 

別のタイプ、例えばアレイを構築するために、1つのタイプのアレイを走査例を構築している場合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方法と、(1がスキャンされると)同じ型の配列を生成するために、そのコレクタのように、あなたは一般的なT含む必要はないと思いますが、代わりにIterator.Elementタイプを使用することができれば上記の拡張機能のT

関連する問題