理解Golang多重赋值

栏目: Go · 发布时间: 5年前

内容简介:Golang 的多重赋值可以用于值交换操作两个值可以方便的如下交换:四个值同样可以如下交换

Golang 的多重赋值可以用于值交换操作

两个值可以方便的如下交换:

a, b = b, a

四个值同样可以如下交换

a, b, c, d = b, c, a, d

那这个交换底层是怎么实现的呢? 我们来做个试验,看看这一段四值交换 golang 代码的的汇编代码

func main(){
    a := 1
    b := 2
    c := 3
    d := 4
    a, b, c, d = b, c, a, d
}
$>dlv debug main.go
Type 'help' for list of commands.
(dlv) b main.main
Breakpoint 1 set at 0x454b6a for main.main() ~/pathToProject/main.go:3
(dlv) r
Process restarted with PID 26528
(dlv) c
> main.main() ~/pathToProject/main.go:3 (hits goroutine(1):1 total:1) (PC: 0x454b6a)
     1: package main
     2:
=>   3: func main() {
     4:         a := 1
     5:         b := 2
     6:         c := 3
     7:         d := 4
(dlv) disassemble
TEXT main.main(SB) D:/Users/polar/go/src/mylab/main.go
        main.go:3       0x454b50        65488b0c2528000000      mov rcx, qword ptr gs:[0x28]
        main.go:3       0x454b59        488b8900000000          mov rcx, qword ptr [rcx]
        main.go:3       0x454b60        483b6110                cmp rsp, qword ptr [rcx+0x10]
        main.go:3       0x454b64        0f8619020000            jbe 0x454d83
=>      main.go:3       0x454b6a*       4883ec50                sub rsp, 0x50
        main.go:3       0x454b6e        48896c2448              mov qword ptr [rsp+0x48], rbp
        main.go:3       0x454b73        488d6c2448              lea rbp, ptr [rsp+0x48]
        main.go:4       0x454b78        48c744242801000000      mov qword ptr [rsp+0x28], 0x1  // a := 1
        main.go:5       0x454b81        48c744242002000000      mov qword ptr [rsp+0x20], 0x2  // b := 2
        main.go:6       0x454b8a        48c744241803000000      mov qword ptr [rsp+0x18], 0x3  // c := 3
        main.go:7       0x454b93        48c744241004000000      mov qword ptr [rsp+0x10], 0x4  // d := 4
        main.go:9       0x454b9c        488b442428              mov rax, qword ptr [rsp+0x28]
        main.go:9       0x454ba1        4889442440              mov qword ptr [rsp+0x40], rax  // temp = a
        main.go:9       0x454ba6        488b442420              mov rax, qword ptr [rsp+0x20]
        main.go:9       0x454bab        4889442428              mov qword ptr [rsp+0x28], rax  // a = b
        main.go:9       0x454bb0        488b442418              mov rax, qword ptr [rsp+0x18]
        main.go:9       0x454bb5        4889442420              mov qword ptr [rsp+0x20], rax  // b = c
        main.go:9       0x454bba        488b442410              mov rax, qword ptr [rsp+0x10]
        main.go:9       0x454bbf        4889442418              mov qword ptr [rsp+0x18], rax  // c = d
        main.go:9       0x454bc4        488b442440              mov rax, qword ptr [rsp+0x40]
        main.go:9       0x454bc9        4889442410              mov qword ptr [rsp+0x10], rax  // d = temp

很好理解了,就是编译器帮我们在栈上创建了一个临时变量 temp, 然后按顺序交换其他各个变量的值。

那么下面这种情况,会发生什么呢?

a := 1
b := 2
a, b, a = b, a, b

a 和 b 最终的值是多少?

看一下汇编代码就清楚了

main.go:5   0x454b9b 48c744241801000000   mov qword ptr [rsp+0x18], 0x1  // a:=1
main.go:6   0x454ba4 48c744241002000000   mov qword ptr [rsp+0x10], 0x2  // b:=2
main.go:7   0x454bad 488b442418           mov rax, qword ptr [rsp+0x18]
main.go:7   0x454bb2 4889442428           mov qword ptr [rsp+0x28], rax  // aTemp := a
main.go:7   0x454bb7 488b442410           mov rax, qword ptr [rsp+0x10]
main.go:7   0x454bbc 4889442420           mov qword ptr [rsp+0x20], rax  // bTemp := b
main.go:7   0x454bc1 488b442410           mov rax, qword ptr [rsp+0x10]
main.go:7   0x454bc6 4889442418           mov qword ptr [rsp+0x18], rax  // a = b
main.go:7   0x454bcb 488b442428           mov rax, qword ptr [rsp+0x28]
main.go:7   0x454bd0 4889442410           mov qword ptr [rsp+0x10], rax  // b = aTemp
main.go:7   0x454bd5 488b442420           mov rax, qword ptr [rsp+0x20]
main.go:7   0x454bda 4889442418           mov qword ptr [rsp+0x18], rax  // a = bTemp

相当于

aTemp = a
bTemp = b
a, b, a = bTemp, aTemp, bTemp

这里两个值交换的操作的原理是将两个被赋值的变量的值,都存储在临时变量里,然后再用临时变量去赋值。所以这个例子赋值顺序对结果是无影响的,其结果仍然是 a = 2, b = 1。

不用再像 C 语言那样写交换函数再内联了,相当于把脏活丢给编译器干了。


以上所述就是小编给大家介绍的《理解Golang多重赋值》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Bulletproof Web Design

Bulletproof Web Design

Dan Cederholm / New Riders Press / 28 July, 2005 / $39.99

No matter how visually appealing or packed with content a Web site is, it isn't succeeding if it's not reaching the widest possible audience. Designers who get this guide can be assured their Web site......一起来看看 《Bulletproof Web Design》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具