添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

So for-in and .forEach() do not work on Range<String.Index> and I can see why: it's because it needs the original string to move:

let s = "xxxxxxx12345yyyyy"
let a = s.index(s.startIndex, offsetBy: 7)
let b = s.index(s.endIndex, offsetBy: -5)
let r = a ..< b
// how to iterate through r?
// for-in and .forEach() do not work. I see why: because the original string is needed to move
//for i in r {    // Protocol 'Sequence' requires that 'String.Index' conform to 'Strideable'
//    print(i)
//r.forEach {     // Referencing instance method 'forEach' on 'Range' requires that 'String.Index' conform to 'Strideable'
//    print($0)
// this works, but it's clumsy
var i = a
while i < b {
    print(s[i])
    i = s.index(after: i)
// does something like this already exist?
struct StringIndexRangeIterator: Sequence, IteratorProtocol {
    private let string: String
    private var at: String.Index
    private let end: String.Index
    init(_ s: String, range: Range<String.Index>) {
        string = s
        at = range.lowerBound
        end = range.upperBound
    mutating func next() -> String.Index? {
        if at >= end {
            return nil
        } else {
            defer { at = string.index(after: at) }
            return at
extension String {
    func iterator(of range: Range<String.Index>) -> StringIndexRangeIterator {
        StringIndexRangeIterator(self, range: range)
// now it's nice and easy to iterate
for i in s.iterator(of: r) {
    print(s[i])
let a = s.index(s.startIndex, offsetBy: 7)
let b = s.index(s.endIndex, offsetBy: -5)
let r = s[a ..< b]
for each in r {
    print(each)
let a = s.index(s.startIndex, offsetBy: 7)
let b = s.index(s.endIndex, offsetBy: -5)
let r = a ..< b
// or just s[r] if you don't need the index itself, as @masters3d said above.
for i in s.indices[r] {
    print("index \(i) has char \(s[i]) ")
let a = s.index(s.startIndex, offsetBy: 7)
let b = s.index(s.endIndex, offsetBy: -5)
let r = a ..< b
// or just s[r] if you don't need the index itself
for i in s.indices[r] {
    print("index \(i) has char \(s[i])...

I noticed that (with Xcode 12.5) this

extension Collection where Self.Index == Self.Indices.Index {

compiles without any warning, as implied by your statement, but this:

struct S<T: Collection> where T.Index == T.Indices.Index {

results in a warning

"Redundant same-type constraint `T.Index` == `T.Indices.Index`"

Why is this?