【问题标题】:Understanding Swift Index, Range, Distance了解 Swift 索引、范围、距离
【发布时间】:2016-10-31 08:40:22
【问题描述】:

我正在实现对 Swift 的 CollectionType 的扩展,它提供了在集合中查找子序列并找到该子序列范围的能力。我在操场上工作的代码是这样的:

extension CollectionType where Generator.Element:Equatable, Index:ForwardIndexType, SubSequence.Generator.Element == Generator.Element {
    func search<S: CollectionType where S.Generator.Element == Generator.Element, S.Index:ForwardIndexType>(pattern: S) -> Self.Index? {
        return self.lazy.indices.indexOf{
            self[$0..<self.endIndex].startsWith(pattern)
        }
    }

    func rangeOf<S: CollectionType where S.Generator.Element == Generator.Element, S.Index:ForwardIndexType, Index:ForwardIndexType>(pattern: S) -> Range<Index>? {
        if let start = self.search(pattern) {
            var end = start
            for _ in pattern.startIndex..<pattern.endIndex {
                end = end.advancedBy(1)
            }
            return start..<end
        } else {
            return nil
        }
    }
}

简单的游乐场测试用例如下:

let fibs = [1, 1, 2, 3, 5, 8, 13]
if let fidx = fibs.search([3, 5]) {
    print(fibs[..<fidx])                          // prints "[1, 1, 2]\n"
    print(fidx..<fidx.advancedBy([1,1,5].count))  // prints "3..<6\n"
}
if let rng = fibs.rangeOf([5,8,13]) {
    print(rng)                                   // prints "4..<7\n"
}

但是,在 rangeOf 函数中,而不是循环

            for _ in pattern.startIndex..<pattern.endIndex {
                end = end.advancedBy(1)
            }

我希望能够使用该语句

            end = start.advancedBy(pattern.count, limit: self.endIndex)

或许

           end = start.advancedBy(pattern.endIndex - pattern.startIndex, limit: self.endIndex)

(我确实认识到 limit 参数是多余的;省略它对以下内容没有影响。)最后两个编译器都没有编译,错误为cannot invoke 'advancedBy' with an argument list of type '(S.Index.Distance, limit: Self.Index)'。我的问题是,为什么这两种形式都不可接受? (我想还有其他有效的问题,关于我是否正确地形成了对扩展和函数类型的约束,但由于一个版本有效,我现在忽略了这一点。)

【问题讨论】:

    标签: swift generics collections range swift-extensions


    【解决方案1】:
     end = start.advancedBy(pattern.count, limit: self.endIndex)
    

    无法编译,因为集合 selfpattern 需要 没有相同的Index 类型。

    如果您将约束 S.Index == Index 添加到 rangeOf() 方法,它将编译。

    【讨论】:

    • 解决了这个问题,然后我发现我可以删除许多其他约束。不错。
    猜你喜欢
    • 2013-11-23
    • 2018-05-07
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 2016-11-10
    • 2017-01-05
    • 1970-01-01
    相关资源
    最近更新 更多