Golang - 意外的多任务行为

时间:2014-10-30 15:49:03

标签: go

我正在编写一个模仿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文章中的PopDelete示例。这与我试图做的事情有显着差异吗?

如果您想查看完整代码(包括错误输出的示例和一些用于调试的打印语句),您可以查看this Gist

1 个答案:

答案 0 :(得分:7)

  

The Go Programming Language Specification

     

Assignments

     

转让分两个阶段进行。一,索引的操作数   表达式和指针间接(包括隐式指针)   左边的选择器中的间接和)上的表达式   权利都按照通常的顺序进行评估。第二,任务   按从左到右的顺序进行。

     

Operands

     

操作数表示表达式中的基本值。操作数可以   是一个文字,一个(可能合格的)非空白标识符,表示一个   常量,变量或函数,一个产生一个的方法表达式   函数或带括号的表达式。

     

Order of evaluation

     

评估表达式,赋值或返回的操作数时   语句,所有函数调用,方法调用和通信   操作按词汇从左到右的顺序进行评估。

     

例如,在(函数 - 本地)赋值

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)。