Swap two numbers golang

huangapple go评论78阅读模式
英文:

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的反汇编对于调试非常有帮助 Swap two numbers 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 &gt; 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, &quot;&quot;.b+16(SP) ; copy a to *b+16
0x003b 00059 (swap.go:11)	MOVQ	AX, &quot;&quot;.a+24(SP) ; copy b to *a+24 

Go's disassembly is so helpful to debugging Swap two numbers golang

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.

Here's the full disassembly, if you're interested.

答案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(&quot;a = %d, b = %d\n&quot;, a, b)
  swap_int(&amp;a, &amp;b)
  fmt.Println(&quot;a = %d, b = %d&quot;, a, b)
}

huangapple
  • 本文由 发表于 2016年3月1日 02:49:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/35707222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定