[swift-evolution] Review for: Remove C-style for-loops with conditions and incrementers
Michel Fortin
michel.fortin at michelf.ca
Mon Dec 7 21:11:48 CST 2015
Le 7 déc. 2015 à 21:03, Joe Groff <jgroff at apple.com> a écrit :
> A more accurate (but not particularly pretty) substitution would be to perform the increment as part of the condition:
>
> while { i = increment(i); return cond(i) }() {
> }
That's buggy (and also does not compile). What you want is this:
var i = 0
var first = true
while ({ () -> Bool in if first { first = false } else { i = increment(i) }; return cond(i) }()) {
}
Interestingly, this behaves correctly with both continue, break, and throw. It's not pretty, but this struct will make a little bit easier on the eye:
/// Provide a suitable condition for recreating the control flow of a C-style `for`
/// loop within a `while` loop.
///
/// var loop = CForLoop()
/// var i = 0
/// while loop.test(i < 2, {i += 1}) { ... }
///
/// - Note: You have to make a new controller each time you start a loop.
struct CForLoop {
/// Flag to prevent the increment part from executing on the first iteration of
/// the loop.
private var first = true
/// If this is the first call of test, simply evaluate `predicate` and return
/// its value. Subsequent calls will execute `increment` before evaluating
/// `predicate`.
/// - Parameter predicate: The test condition that must be true for the loop to
/// continue. This is the second statement in a C-style `for` loop.
/// - Parameter increment: The code to execute just before re-evaluating the
/// predicate at the end of one loop iteration. This is the third statement
/// of a C-style `for` loop.
/// - Returns: The value returned by predicate. This value should be used as
/// the condition in a `while` loop.
mutating func test(@autoclosure predicate: () -> Bool, _ increment: () -> ()) -> Bool {
if first {
first = false
} else {
increment()
}
return predicate()
}
}
--
Michel Fortin
michel.fortin at michelf.ca
https://michelf.ca
More information about the swift-evolution
mailing list