丰富的线上&线下活动,深入探索云世界
做任务,得社区积分和周边
最真实的开发者用云体验
让每位学生受益于普惠算力
让创作激发创新
资深技术专家手把手带教
遇见技术追梦人
技术交流,直击现场
海量开发者使用工具、手册,免费下载
极速、全面、稳定、安全的开源镜像
开发手册、白皮书、案例集等实战精华
为开发者定制的Chrome浏览器插件
下面通过列举一些例子,结合ChatGPT来辅助深入理解Go代码实际运行机制,以后遇到类似困惑的时候,都可以通过该方法了解其中的原理。
可以看到上述汇编指令中,第一行从参数p中取地址值的操作没变化,只是从AX寄存器中取值的时候,命令有MOVQ(8字节)变为MOVL(4字节),可见不同类型的指针地址本身是一样的类型(无符号整型)。
直接问ChatGPT,给出的解释是:
反编译调试:
结合上面的分析incr函数中的变量a和变量b的分析如下:
(1)incr中变量a作为局部变量,值是m+n等于3;
(2)在入栈给的时候,传给x的值是a+1等于4;
(3)给a赋值99,a的值变为99;
(4)给b赋值,b的值为99;
(5)赋值给返回地址,取b的值99;
(6)执行defer函数,a的值为a+x,就是99+4,a的值变为103;
(7)b++,b的值变为100(注意在此之前b的值为99时,已经赋给返回地址了);
综上所述,main函数中的c最终的打印值是99。
Tips:go函数defer执行时是先给返回值地址赋值,再执行deferpackagemainimport"fmt"funcmain(){deferA()deferB()deferC()panic("panicA")fmt.Println("funcmain")}funcA(){fmt.Println("funcA")}funcB(){fmt.Println("funcB")}funcC(){fmt.Println("funcC")}