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

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

报告相同问题?

悬赏问题

  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 Macbookpro 连接热点正常上网,连接不了Wi-Fi。
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程