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的泛型子类型Tbe Equatable,但您只能在原始类型声明中提供这些约束,而不能在扩展中提供。

解决方案是声明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

我找到了更好的答案!感谢 Nate 让我走上正轨。

诀窍是比较器需要来自定义类型的顶层。所以,最终的解决方案只有三处变化,在第二行、第十六行和调用中。改变是通过比较器,并使用比较器而不是直接压缩值。

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)]

然后,这可以作为通用 Equatable 协议问题的一般解决方案。

于 2014-10-02T14:35:36.423 回答