我想了解go的内部。请考虑以下代码
a,b := 10,5
b,a = a,b
上面的代码完美地交换2个数字,a变为5,b变为10.我无法理解这是如何工作的。考虑到第二行代码,如果a首先被分配给b,那么b将是10.现在如果我们将b分配给a那么也不应该是10。
请帮助我了解其工作原理
由于
答案 0 :(得分:22)
TL; DR :反汇编表明CPU必须足够聪明才能看到发生了什么,并使用寄存器来避免覆盖内存中的现有值。
这个问题让我对Golang有了更多的了解,谢谢!
为了弄清楚编译器如何生成本机代码,我们需要查看它生成的汇编代码,链接器将其转换为机器代码。
我写了一个Go程序来帮助解决这个问题:
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
,然后 CTRL - F 'd代表myfunction
(这个名称的重点:易于搜索),并找到这四行,对应于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
Go的反汇编对调试很有帮助:D
查看the Golang docs on asm,我们可以看到汇编程序使用间接来处理值。
当程序运行时,CPU足够聪明,可以看到发生了什么,并使用寄存器来避免覆盖现有值。