上图中main方法中声明了a和b两个变量,然后通过swap2方法完成值交换。很简单的过程。(通过地址值进行引用然后完成交换)
图右边是代码的在栈帧的的一个交换过程:
大概说一下:
- 首先初始化的main方法在栈帧 有两个内存空间 分别为
0xaa00
和0xbb00
对应a和b的变量地址 - 然后运行到调用swap2 产生栈帧空间,空间内 有x和y两个变量形参。
- 然后swap2(&a,&b) 去地址值的方式把a和b的地址给了swap2方法 ,
- swap2方法 的
*x,*y=*y,*x
是做了一个值交换,首先第一个*x
是取内存空间(我们之前说过 :等号左边的变量,代表变量所指向的内存空间
)这里通俗来说就是*x
是去main方法的栈帧下取到a的地址值(0xaa00)。 - 第三个
*y
是根据地址把值取(等号右边的变量,代表变量内存空间存储的数据值
)到然后赋值给*x
(0xaa00),取得的值为20 转化一下:0xaa00=20
一通百通
再来一个demo
主要看 new
, new
这个关键字是去(heap)堆内存申请一块内存空间,下面var p=new(*int)
申请指针类型的内存 ,返回的是一块内存空间的地址值为0xc00001e090
,想要给它赋值就必须进行取到0xc00001e090地址的空间*p,然后赋值*p=&i
,这个时候根据*p
取得值是i的地址0xc0000be008值不是数据值,想要取得i的值需要再加个*
就是**p
,才能取到i的值。绕的一笔
func main() {
var p =new(*int) //p 0xc00001e090
var i int
i=1000
*p=&i
fmt.Println(&i) // 0xc0000be008 i地址值
fmt.Println(*p) // 0xc0000be008 i地址值
fmt.Println(p) //0xc00001e090 p变量的内存地址值
fmt.Println(**p) // 1000 i的数据值1000
}