Golang-意外的多重分配行为

I'm writing a Go function that kind of mimics Python's itertools.permutations(), but returning all permutations at once instead of yielding one at a time.

I'm seeing unexpected behavior when updating 2 variables at the same time in the following lines of code:

setcopy := append([]int(nil), sorted...)
for i := 0; i < r; i++ {
    c := counters[r-1-i]
    current[i], setcopy = setcopy[c], append(setcopy[:c], setcopy[c+1:]...)
}

I get correct results when decoupling the above update:

current[i] = setcopy[c]
setcopy = append(setcopy[:c], setcopy[c+1:]...)

I was mainly inspired by the Pop and Delete examples from the SliceTricks wiki article. Is there a significant difference between that and what I'm trying to do?

If you'd like to check out the full code (including an example of the faulty output and some print statements for debugging), you can check out this Gist.

The Go Programming Language Specification

Assignments

The assignment proceeds in two phases. First, the operands of index expressions and pointer indirections (including implicit pointer indirections in selectors) on the left and the expressions on the right are all evaluated in the usual order. Second, the assignments are carried out in left-to-right order.

Operands

Operands denote the elementary values in an expression. An operand may be a literal, a (possibly qualified) non-blank identifier denoting a constant, variable, or function, a method expression yielding a function, or a parenthesized expression.

Order of evaluation

When evaluating the operands of an expression, assignment, or return statement, all function calls, method calls, and communication operations are evaluated in lexical left-to-right order.

For example, in the (function-local) assignment

y[f()], ok = g(h(), i()+x[j()], <-c), k()

the function calls and communication happen in the order f(), h(), i(), j(), <-c, g(), and k(). However, the order of those events compared to the evaluation and indexing of x and the evaluation of y is not specified.

Appending to and copying slices

If the capacity of s is not large enough to fit the additional values, append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array.

Is a new underlying array is being allocated?

The assignment statement

current[i], setcopy = setcopy[c], append(setcopy[:c], setcopy[c+1:]...)

appears to be equivalent to

a := append(setcopy[:c], setcopy[c+1:]...)
x := setcopy[c]
y := a
current[i], setcopy = x, y

but the order of function call events compared to evaluation of other operands is not specified (Order of evaluation).