我正在编写一个模仿Python itertools.permutations()
的Go函数,但是一次返回所有排列,而不是一次只返回一个。
我在以下代码行中同时更新2个变量时发现意外行为:
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:]...)
}
在解耦上述更新时,我得到了正确的结果:
current[i] = setcopy[c]
setcopy = append(setcopy[:c], setcopy[c+1:]...)
我的主要灵感来自SliceTricks wiki文章中的Pop
和Delete
示例。这与我试图做的事情有显着差异吗?
如果您想查看完整代码(包括错误输出的示例和一些用于调试的打印语句),您可以查看this Gist。
答案 0 :(得分:7)
The Go Programming Language Specification
转让分两个阶段进行。一,索引的操作数 表达式和指针间接(包括隐式指针) 左边的选择器中的间接和)上的表达式 权利都按照通常的顺序进行评估。第二,任务 按从左到右的顺序进行。
操作数表示表达式中的基本值。操作数可以 是一个文字,一个(可能合格的)非空白标识符,表示一个 常量,变量或函数,一个产生一个的方法表达式 函数或带括号的表达式。
评估表达式,赋值或返回的操作数时 语句,所有函数调用,方法调用和通信 操作按词汇从左到右的顺序进行评估。
例如,在(函数 - 本地)赋值
中y[f()], ok = g(h(), i()+x[j()], <-c), k()
函数调用和通信以f(),h()的顺序发生, i(),j(),&lt; -c,g()和k()。但是,那些事件的顺序 与x的评估和索引以及y的评估相比较 未指定。
Appending to and copying slices
如果s的容量不足以容纳附加值, append分配一个适合的新的,足够大的底层数组 现有的切片元素和附加值。除此以外, append重新使用底层数组。
是否正在分配新的基础数组?
转让声明
current[i], setcopy = setcopy[c], append(setcopy[:c], setcopy[c+1:]...)
似乎等同于
a := append(setcopy[:c], setcopy[c+1:]...)
x := setcopy[c]
y := a
current[i], setcopy = x, y
但未指定与其他操作数的评估相比的函数调用事件的顺序(Order of evaluation)。