1

誰でもこのバグに光を当てることができますか? プレイグラウンドは、引数 #2 が欠落していると主張しますが、引数 #1 はありません!

同等の値の実行回数をカウントし、値とそのカウントで構成される一連のタプルを返すというコードの意図。私はこのコードに広範囲に取り組み、それが機能するはずだと確信できるまで最適化し、改良しました... しかし、コンパイルはできますが、意図したとおりに呼び出すことはできません。

以下のコードを呼び出すことで得られるエラーはmissing argument for parameter #2 in call

extension SequenceOf {
    func CountRuns<T: Equatable>() -> SequenceOf<(T, Int)> {
        return SequenceOf<(T, Int)>([])
        return SequenceOf<(T, Int)> { () -> GeneratorOf<(T, Int)> in
            var generator = self.generate()
            var previousValue: T?
            var start = true
            return GeneratorOf<(T, Int)> { () -> (T, Int)? in
                var count = 1
                var retValue: (T, Int)?
                while(true) {
                    var value = generator.next() as T?
                    if start {
                        previousValue = value
                        start = false
                    } else if value != nil && value! == previousValue! {
                        count++
                    } else {
                        if previousValue != nil {
                            retValue = (previousValue!, count)
                        }
                        previousValue = value
                        break
                    }
                }
                return retValue
            }
        }
    }
}

println(SequenceOf(y).CountRuns())

Playground execution failed: <EXPR>:327:23: error: missing argument for parameter #2 in call
println(SequenceOf(y).CountRuns())
                      ^
4

2 に答える 2

1

あなたが抱えている問題は、ジェネリックサブタイプをさらに特殊化するメソッドでジェネリック型を実際に拡張できないことです。つまり、countRunsメソッドではSequenceOfのジェネリック サブタイプTEquatableである必要がありますが、拡張機能ではなく、元の型宣言でのみこれらの制約を提供できます。

countRuns解決策は、次のように最上位関数として宣言することです。

func countRuns<T: Equatable>(s: SequenceOf<T>) -> SequenceOf<(T, Int)> {
    return SequenceOf<(T, Int)> { () -> GeneratorOf<(T, Int)> in

        // note the change from self.generate() to s.generate() here
        var generator = s.generate()

        var previousValue: T?
        var start = true
        return GeneratorOf<(T, Int)> { () -> (T, Int)? in
            var count = 1
            var retValue: (T, Int)?
            while(true) {
                var value = generator.next() as T?
                if start {
                    previousValue = value
                    start = false
                } else if value != nil && value! == previousValue! {
                    count++
                } else {
                    if previousValue != nil {
                        retValue = (previousValue!, count)
                    }
                    previousValue = value
                    break
                }
            }
            return retValue
        }
    }
}

println(countRuns(SequenceOf(y)))

これについては、この NSHipster の記事の最後で (少し)説明しました。

于 2014-10-02T08:13:38.730 に答える
0

より良い答えを見つけました!私を正しい軌道に乗せてくれたネイトに感謝します。

秘訣は、型が定義されているトップレベルからコンパレーターを取得する必要があることです。したがって、最終的なソリューションには、2 行目、16 行目、および呼び出しの 3 つの変更のみがあります。変更は、コンパレータを渡し、値を直接圧縮する代わりにコンパレータを使用することです。

extension SequenceOf {
    func CountRuns(areEqual: (T, T) -> Bool) -> SequenceOf<(T, Int)> {
        return SequenceOf<(T, Int)>([])
        return SequenceOf<(T, Int)> { () -> GeneratorOf<(T, Int)> in
            var generator = self.generate()
            var previousValue: T?
            var start = true
            return GeneratorOf<(T, Int)> { () -> (T, Int)? in
                var count = 1
                var retValue: (T, Int)?
                while(true) {
                    var value = generator.next() as T?
                    if start {
                        previousValue = value
                        start = false
                    } else if value != nil && areEqual(value!, previousValue!) {
                        count++
                    } else {
                        if previousValue != nil {
                            retValue = (previousValue!, count)
                        }
                        previousValue = value
                        break
                    }
                }
                return retValue
            }
        }
    }
}

let y = [0, 0, 0, 2, 2, 2, 3, 4 ,4, 5, 65, 65]
println(SequenceOf(y).CountRuns(==).ToArray())
let z = [0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 3.0, 4.0, 4.0, 5.0, 65.0, 65.0]
println(SequenceOf(z).CountRuns(==).ToArray())

// Prints:
// [(0, 3), (2, 3), (3, 1), (4, 2), (5, 1), (65, 2)]
// [(0.0, 3), (2.0, 3), (3.0, 1), (4.0, 2), (5.0, 1), (65.0, 2)]

これは、Generic Equatable プロトコルの問題に対する一般的な解決策として機能します。

于 2014-10-02T14:35:36.423 に答える