Whereas constructing a quite simple caching system, I got here throughout a situation the place I’ve a slice that, as I iterate over it, will get consumed. New incoming information will get appended onto the slice and sendoff is dealt with by sending off slice[0] (assuming len() > 0 checks out) and rebuilding the slice with myslice = myslice[1:]
. I re-implemented one thing comparable right here:
func principal() {
var finval []int = []int{1, 2, 3, 4, 5, 6, 7}
var lenfin = len(finval)
//for i := 0; i < len(finval); i++{
for i := 0; i < lenfin; i++ {
fmt.Println(i, ":", finval[0])
finval = finval[1:]
}
}
I seen that, whereas enjoying round with this simplified model, the commented out line re-checks the size of finval whereas iterating, resulting in the output
0 : 1
1 : 2
2 : 3
3 : 4
as a substitute of the anticipated and applicable
0 : 1
1 : 2
2 : 3
3 : 4
4 : 5
5 : 6
6 : 7
It appears apparent to me that as every loop cycles over, it re-checks the size. I’m unsure why, however I’d have anticipated the size worth to be checked initially and never modified. Am I flawed to count on this? Is there a technical cause that is carried out this fashion? I’d have thought that some black magic involving pointers could be wanted to have it re-check each loop.
It reevaluates the ending situation after every iteration and the finval size is altering contained in the loop
really for loop in Go like this
func principal() {
var finval []int = []int{1, 2, 3, 4, 5, 6, 7}
var lenfin = len(finval)
var i int = 0
whereas i < lenfin {
fmt.Println(i, ":", finval[0])
finval = finval[1:]
i++
}
}
should you verify len in loop will like this:
func principal() {
var finval []int = []int{1, 2, 3, 4, 5, 6, 7}
var lenfin = len(finval)
var i int = 0
whereas i < lenfin {
fmt.Println(i, ":", finval[0])
finval = finval[1:]
lenfin = len(finval) // right here verify once more
i++
}
}
There was an identical dialogue right here, perhaps it could actually enable you
Contemplate the next code:
func principal() {
shiftingTarget := 100
for i := 0; i < shiftingTarget; i++ {
shiftingTarget--
}
fmt.Println("All finished and shifting goal is", shiftingTarget)
}
That behaves precisely how you’ll count on, proper? And should you invert it to for i := 0; shiftingTarget > i; i++ {
you’ll ALSO count on it to work, proper? So how would the compiler know which properties you count on to be fixed? From the tour of go (emphasis mine):
The fundamental
for
loop has three elements separated by semicolons:
- the init assertion: executed earlier than the primary iteration
- the situation expression: evaluated earlier than each iteration
- the publish assertion: executed on the finish of each iteration
There’s nothing particular in regards to the init/situation/publish assertion. You might write the next should you wished:
func principal() {
i := 0
for fmt.Println("init"); situation(); fmt.Println("publish") {
if i == 10 {
break
}
i++
}
}
func situation() bool {
fmt.Println("situation")
return true
}
That stated, I believe your loop would in all probability be extra precisely and easily represented like this:
func principal() {
finval := []int{1, 2, 3, 4, 5, 6, 7}
// Course of all of the objects in our slice
for len(finval) > 0 {
fmt.Println(finval[0])
finval = finval[1:]
}
}