The post part of for statement: what if one wants to adjust more than one variable?

In almost all for examples I can see for i := 0; i < 10; i++ {.

What if one wanted to do more than one i++ in the post part?
For example I wanted to (something like) { i++; j -= 10; z *= 3 }.

The reference is not crystal clear (for me):

Assignment = ExpressionList assign_op ExpressionList .
assign_op = [ add_op | mul_op ] "=" .

Suggests that something like i, j, k += 1, -10, 3 would be possible (but it seems that not).

The PostStmt is a SimpleStmt.

SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .

You can only use one (|) of these statements. If you use an IncDecStmt i++ you are done.

If you use an Assignment you can of course do

i, j, k = 1, -10, 3

but you can’t do

i, j, k += 1, -10, 3

because += is neither an add_op nor a mult_op.

For example - https://play.golang.org/p/rEm0IJIef0

for i, j := 0, 10; i < j; i, j = i+1, j-1 {
	fmt.Println("Hello, playground")
}

Now I will preface this by saying this code quickly becomes harder to read if you get too complex, so I would err on the side of caution when doing this.

4 Likes

If the update clause is too complex for using the multi-assignment solution that @joncalhoun and @lutzhorn proposed, consider adjusting the variables within the loop body instead.

4 Likes

It is not the += which has to be add_op.

i, j, k : ExpressionList
+= : assign_op
1, -10, 3 : ExpressionList

+ : add_op
= : “=”

This does not work (https://play.golang.org/p/dW-4NIoseO):

package main

import "fmt"

func main() {
	i, j, k := 1, 2, 3
	i, j, k += 1, 1, 1
	fmt.Println(i)
	fmt.Println(j)
	fmt.Println(k)
}

Error:

tmp/sandbox618335955/main.go:7: syntax error: unexpected +=, expecting := or = or comma

So what do you propose regarding the original question of being able to do i, j, k += 1, -10, 3?

The i, j = i+1, j-1 works, but i = i+1 is slightly different from i += 1 (evaluation count). (And one assignment, even if tuple-assignment, can not always be enough if the “continue” part of the loop.)

consider adjusting the variables within the loop

And use goto
continue would be a bit safer and nicer than goto.

Maybe i, j, k += 1, 1, 1 “syntactically” is correct, but “semantically” is not.

https://golang.org/ref/spec#Assignment contains a sentence:

In assignment operations, both the left- and right-hand expression lists must contain exactly one single-valued expression

Probably this wanted to mean that assignments take the form either
ExpressionList “=” ExpressionList
either
Expression ( add_op | mul_op ) “=” Expression
So with add_op or mul_op, lists (elements with at least one comma) are not permitted.

No, it is not syntactially correct. Just run the Play and see.

Don’t guess on the syntax, read the definiton and the error the compiler is giving you.

I have made a separate note regarding the definition (which I have read).

consider adjusting the variables within the loop

And use goto…
continue would be a bit safer and nicer than goto.

Not sure if I understand what you are trying to say.

What I meant with “adjusting the variables within the loop” is, if the post part is going to get too complex, move it into the loop body instead. For example, taking your initial post operation, you can move it to the end of the loop body like so:

for <init>; <conditions>; {
    ... do something here ...
    i++; j -= 10; z *= 3
}
1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.