使用辅助函数(最初在将使用除法的C样式for循环转换为Swift3时定义
public func sequence<T>(first: T, while condition: @escaping (T)-> Bool, next: @escaping (T) -> T) -> UnfoldSequence<T, T> { let nextState = { (state: inout T) -> T? in // Return `nil` if condition is no longer satisfied: guard condition(state) else { return nil } // Update current value _after_ returning from this call: defer { state = next(state) } // Return current value: return state } return sequence(state: first, next: nextState)}您可以将循环写为
let num = 1000for i in sequence(first: 5, while: { num/$0 > 0 }, next: { $0 * 5 }) { print(i)}一个更简单的解决方案是while循环:
var i = 5while num/i > 0 { print(i) i *= 5}但是第一种解决方案的优点是,循环变量的范围仅限于循环主体,并且循环变量是常量。
Swift 3.1 将提供一个
prefix(while:)sequence的方法,然后不再需要helper函数:
let num = 1000for i in sequence(first: 5, next: { $0 * 5 }).prefix(while: { num/$0 > 0 }) { print(i)}以上所有解决方案均与给定的C循环“等效”。 但是, 如果它们
num接近
Int.max并
$0 * 5溢出 ,
它们都可能崩溃。如果这是一个问题,那么在进行乘法运算 之前, 您必须检查是否
$0 * 5适合整数范围。 __
实际上,这使循环更简单–至少如果我们假设
num >= 5这样,则循环至少执行一次:
for i in sequence(first: 5, next: { $0 <= num/5 ? $0 * 5 : nil }) { print(i)}


