Counter as a variable for in-in-loop

When an in-in-loop is commonly used, the counter (in this case, number ) is a constant at each iteration:

 for number in 1...10 { // do something } 

This means that I cannot change the number in the loop:

 for number in 1...10 { if number == 5 { ++number } } // doesn't compile, since the prefix operator '++' can't be performed on the constant 'number' 

Is there a way to declare number as a variable without declaring it before the loop, or using a regular for loop (with initialization, condition and increment)?

+7
source share
3 answers

To understand why i can not be mutable means knowing what for…in means. for i in 0..<10 extended by the compiler to the following:

 var g = (0..<10).generate() while let i = g.next() { // use i } 

Each time in loop i is the just declared variable, the value of the expansion of the next result when next called on the generator.

Now, that while can be written as follows:

 while var i = g.next() { // here you _can_ increment i: if i == 5 { ++i } } 

but of course that would not help - g.next() is still going to generate 5 next time around the loop. The increment of the body was meaningless.

Presumably for this reason, for…in does not support the same var syntax for declaring its loop counter - it would be very confusing if you did not understand how this works.

(unlike where , where you can see what happens - the var functionality is sometimes useful, just like func f(var i) can be).

If you want to skip certain iterations of the loop, your best bet (without resorting to C-style for or while ) is to use a generator that skips the corresponding values:

 // iterate over every other integer for i in 0.stride(to: 10, by: 2) { print(i) } // skip a specific number for i in (0..<10).filter({ $0 != 5 }) { print(i) } let a = ["one","two","three","four"] // ok so this one's a bit convoluted... let everyOther = a.enumerate().filter { $0.0 % 2 == 0 }.map { $0.1 }.lazy for s in everyOther { print(s) } 
+14
source

The answer is no, and that’s good. Otherwise there would be a rudely confusing behavior like this:

 for number in 1...10 { if number == 5 { // This does not work number = 5000 } println(number) } 

Imagine the confusion that someone is looking at the number 5000 at the end of a loop, presumably related to a range of 1, although 10 inclusive.

Also, what would Swift choose the next value of 5000? Is it worth it to stop? Should it continue until the next number in the range before destination? Should it throw an exception to the job out of range? All three options have a certain value for them, so there is no clear winner.

To avoid such situations, Swift designers turned cycle variables into range cycles unchanged.

+2
source

Brothers nbgijnjghurgrflknjbknjr3egnjr3ngoefgnjfenbrfjeowhn

0
source

Source: https://habr.com/ru/post/981802/


All Articles