2016-06-28 38 views
1

我對Swift的CollectionType實現了擴展,它提供了在集合中查找子序列並查找該子序列範圍的功能。我的代碼的工作在操場是這樣的:瞭解Swift索引,範圍,距離

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) 

(我也認識到,限制參數是多餘的;省略它在下面沒有任何區別)。最後兩個都沒有編譯,錯誤爲cannot invoke 'advancedBy' with an argument list of type '(S.Index.Distance, limit: Self.Index)'。我的問題是,爲什麼這兩種形式都不能被接受? (我想還有其他有效的問題,即是否我已經正確形成類型的擴展名的約束和功能,但是由於一個版本的作品,我忽略了現在。)

回答

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

不編譯,因爲收集selfpattern需要 不具有相同的Index類型。

它編譯如果您將約束S.Index == Index添加到rangeOf()方法。

+0

修復後,我發現我可以刪除許多其他限制。尼斯。 – Feldur