我在试着了解围棋的内部 struct .请考虑以下代码
a,b := 10,5
b,a = a,b
上面的代码完美地交换了2个数字,a变成了5,b变成了10.我不能理解这是如何工作的.考虑第二行代码,如果a先赋给b,那么b应该是10,现在如果我们把b赋给a,那么a不应该也是10吗?
请帮我了解一下这是怎么回事
谢谢
我在试着了解围棋的内部 struct .请考虑以下代码
a,b := 10,5
b,a = a,b
上面的代码完美地交换了2个数字,a变成了5,b变成了10.我不能理解这是如何工作的.考虑第二行代码,如果a先赋给b,那么b应该是10,现在如果我们把b赋给a,那么a不应该也是10吗?
请帮我了解一下这是怎么回事
谢谢
TL;DR:反汇编表明CPU必须足够智能,能够看到正在发生的事情,并使用寄存器来避免覆盖内存中的现有值.
这个问题让我对golang 有了更多的了解,所以谢谢!
要弄清楚编译器是如何生成本机代码的,我们需要查看它生成的汇编代码,这些代码被链接器转换为机器码.
我写了一个小围棋程序来帮助解决这个问题:
package main
import "fmt"
func main() {
fmt.Println(myfunction())
}
func myfunction() []int {
a, b := 10, 5
b, a = a, b
return []int{a, b}
}
然后使用go tool compile -S > swap.s
,我对myfunction
使用了CTRL-F(这就是这个名字的意义:易于搜索),并找到了这四行,这四行对应于Go代码中myfunction
的前两行:(注意这是我的64位机器;其他架构(如32位)的输出会有所不同)
0x0028 00040 (swap.go:10) MOVQ $10, CX ; var a = 10
0x002f 00047 (swap.go:10) MOVQ $5, AX ; var b = 5
0x0036 00054 (swap.go:11) MOVQ CX, "".b+16(SP) ; copy a to *b+16
0x003b 00059 (swap.go:11) MOVQ AX, "".a+24(SP) ; copy b to *a+24
围棋的反汇编对调试非常有帮助:d
看一下the Golang docs on asm,我们可以看到汇编器使用间接的方式来变化值.
当程序运行时,CPU足够智能,可以看到正在发生的事情,并使用寄存器来避免覆盖现有值.