go的多重赋值问题

package main

import ("fmt")

func fibonacci() func(int) int {
    pre_pre, pre := 1, 1;
    return func(x int) int {
        if x == 0 || x == 1 {
            return pre
        } else {
            tmp := pre_pre + pre

            //第一种
            //pre_pre = pre
            //pre = tmp

            //第二种
            //pre_pre, pre = pre, tmp

            //第三种
            pre, pre_pre = tmp, pre

            return tmp
        }
    } 
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f(i))
    }
}

用迭代输出斐波那契数列,在迭代数列中两个前置数的时候,我用了3种方法:
注释中的第一种,最常见的。
注释中的第二种和第三种,用了go的多重赋值的特性。
关键是:第二种第三种都能正确输出数列
这我就纳闷了,这个多重赋值的执行顺序到底是怎样的?它是怎么正确解析出我的赋值步骤的(即第一种里面的步骤)?

阅读 6.1k
2 个回答

执行顺序从左到右,但左边被赋值的变量在表达式的下一行才生效。

a, b = b, a+1 可理解成

temp_a = a
a = b
b = temp_a + 1

更多例子 https://golang.org/ref/spec#A...

a, b = b, a  // exchange a and b

x := []int{1, 2, 3}
i := 0
i, x[i] = 1, 2  // set i = 1, x[0] = 2

i = 0
x[i], i = 2, 1  // set x[0] = 2, i = 1

x[0], x[0] = 1, 2  // set x[0] = 1, then x[0] = 2 (so x[0] == 2 at end)

x[1], x[3] = 4, 5  // set x[1] = 4, then panic setting x[3] = 5.

type Point struct { x, y int }
var p *Point
x[2], p.x = 6, 7  // set x[2] = 6, then panic setting p.x = 7

i = 2
x = []int{3, 5, 7}
for i, x[i] = range x {  // set i, x[2] = 0, x[0]
    break
}
// after this loop, i == 0 and x == []int{3, 5, 3}

规范要求赋值语句的右边表达式先被求值.

所以

pre, pre_pre = tmp, pre

在求值后就是

// 假设 tem = 3, pre = 2
pre, pre_pre = 3, 2
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题