dqz7636 2014-10-30 15:49
浏览 26
已采纳

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.

  • 写回答

1条回答 默认 最新

  • douxiandiyo58855 2014-10-30 16:12
    关注

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法