在Swift 2.2+中使用AnyGenerator(“for in”循环支持自定义类)

以前我使用下面的函数来使我的自定义类符合SequenceType协议:

func generate() -> AnyGenerator<UInt32> { var nextIndex = 0 return anyGenerator { if (nextIndex > self.scalarArray.count-1) { return nil } return self.scalarArray[nextIndex++] } } 

这与接受的这两个问题的答案类似。

  • 添加“for in”支持来遍历Swift自定义类
  • 在Swift 2中添加'for … in'支持类

但是在Swift 2.2更新之后…

“++”已被弃用:它将在Swift 3中被删除

 func generate() -> AnyGenerator<UInt32> { var nextIndex = 0 return AnyGenerator { if (nextIndex > self.scalarArray.count-1) { return nil } nextIndex += 1 return self.scalarArray[nextIndex] } } 

但是这会引发索引超出范围错误,因为我实际上需要使用预先递增的索引,然后在返回之后将其增加。

现在在Swift中,AnyGenerator如何工作? (另外,我应该减less而不是增加,因为我连接的另外两个答案呢?)

(我认为你的代码是通过在Swift中使用Unicode代码点来引用struct ScalarString )。

你可以用defer做一个Swift 2.2+兼容的“确定返回值后的增量索引”:

 func generate() -> AnyGenerator<UInt32> { var nextIndex = 0 return AnyGenerator { if nextIndex >= self.scalarArray.count { return nil } defer { nextIndex += 1 } return self.scalarArray[nextIndex] } } 

然而,在你的特殊情况下,只是转发发电机将会更容易

 private var scalarArray: [UInt32] = [] 

财产,直接:

 func generate() -> IndexingGenerator<[UInt32]> { return scalarArray.generate() } 

或者作为将next()方法转发给数组生成器的types擦除生成器:

 func generate() -> AnyGenerator<UInt32> { return AnyGenerator(scalarArray.generate()) } 

你为什么不引入一个虚拟variables?

 func generate() -> AnyGenerator<UInt32> { var nextIndex = 0 return AnyGenerator { if (nextIndex > self.scalarArray.count-1) { return nil } let next = self.scalarArray[nextIndex] nextIndex += 1 return next }