英文:
Swap two numbers golang
问题
我正在尝试理解Go语言的内部机制。考虑以下代码:
a, b := 10, 5
b, a = a, b
上述代码完美地交换了两个数字,a变成了5,b变成了10。我无法理解这是如何实现的。考虑到代码的第二行,如果先将a赋值给b,那么b应该是10。现在如果我们将b赋值给a,那么a不也应该是10吗?
请帮助我理解这是如何工作的。
谢谢。
英文:
I am trying to understand the internals of go. Consider the following code
a,b := 10,5
b,a = a,b
The above code swaps 2 number perfectly and a becomes 5 and b becomes 10. I am not able to understand how this works. Considering in the second line of code, if a is assigned to b first, then b would be 10. Now if we assign b to a then shouldn't a be 10 too.
Please help me understand how this works
Thanks
答案1
得分: 46
这个问题帮助我更多地了解了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
命令,然后在汇编代码中搜索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
Golang的反汇编对于调试非常有帮助
从Golang的汇编文档中可以看出,汇编器使用间接寻址来处理这些值。
当程序运行时,CPU足够聪明,能够看到发生的情况,并使用寄存器来避免覆盖现有的值。
英文:
TL;DR: The disassembly shows that the CPU must be smart enough to see what's happening and use a register to avoid overwriting the existing value in memory.
This question helped me learn a little more about Golang, so thank you!
To figure out how the compiler makes native code, we need to look at the assembly code it generates, which is turned into machine code by the linker.
I wrote a little Go program to help with this:
package main
import "fmt"
func main() {
fmt.Println(myfunction())
}
func myfunction() []int {
a, b := 10, 5
b, a = a, b
return []int{a, b}
}
Using go tool compile -S > swap.s
, I then <kbd>CTRL - F</kbd>'d for myfunction
(which was the point of that name: easily searchable), and found these four lines, which correspond to the first two lines of myfunction
in the Go code: (note this is for my 64-bit machine; the output will differ on other architechtures like 32-bit)
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's disassembly is so helpful to debugging
Looking at the Golang docs on asm, we can see the assembler uses indirection to juggle the values.
When the program runs, the CPU is smart enough to see what's happening and use a register to avoid overwriting the existing value.
答案2
得分: 1
值得注意的是,在Go语言中,当我们使用a,b=b,a时,Go运行时会使用位操作来执行内部交换。
在交换两个变量时,Go运行时会内部使用位操作XOR来交换值。
这比传统的方法更快,传统方法使用一个临时变量来存储其中一个值。
英文:
It's worth noting that in go, when we use a,b=b,a the Go runtime uses bitwise operation to perform the swapping internally.
When swapping two variable, the Go runtime will internally use bitwise operation XOR to swap the values.
It's faster than the traditional way which uses a temporary variable to store one of the values.
答案3
得分: -3
这是我用Go语言实现的交换数字的代码:
func swap_int(a *int, b *int) {
var x int
x = *a
*a = *b
*b = x
}
func main() {
var a int = 40
var b int = 32
fmt.Println("a =", a, ", b =", b)
swap_int(&a, &b)
fmt.Println("a =", a, ", b =", b)
}
希望对你有帮助!
英文:
here's my implementation of swapping numbers in Go:
func swap_int(a *int, b *int) {
var x int
x = *a
*a = *b
*b = x
}
func main() {
var a int = 40
var b int = 32
fmt.Println("a = %d, b = %d\n", a, b)
swap_int(&a, &b)
fmt.Println("a = %d, b = %d", a, b)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论