【问题标题】:Swift: Missing argument in call to argumentless extension of SequenceOfSwift:调用 SequenceOf 的无参数扩展时缺少参数
【发布时间】:2014-10-02 07:32:30
【问题描述】:

有人能看出这个错误吗?操场坚持认为缺少参数 #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())
                      ^

【问题讨论】:

    标签: swift arguments ios8 sequence ios8-extension


    【解决方案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)))
    

    这在this NSHipster article 的末尾被覆盖(一点点)。

    【讨论】:

    • 嗯……这行得通。不是我想要的,因为我想做链接。
    【解决方案2】:

    我找到了更好的答案!感谢 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 协议问题的一般解决方案。

    【讨论】:

      猜你喜欢
      • 2015-03-16
      • 1970-01-01
      • 2014-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-15
      相关资源
      最近更新 更多