1、变量地址
- 变量本质就是内存中一块数据的标记,把值存储到变量中实质就是把值存储到内存中。
- 每次对变量重新赋值就是在修改变量地址中的内容。
- 在go语言中可以通过&+变量名获取到变量地址值。
- 重新创建一个非引用型变量(即使是把已有变量直接赋值给新变量)也会新开辟内存地址。
func main(){
a := 3
fmt.Println(&a)//0xc00000a0b8
a = 4
fmt.Println(&a)//0xc00000a0b8
}
变量在创建的时候就在内存中开辟了一块空间,我们为变量赋值就是把值存储到改变量对应的内存空间中。当对变量重新赋值时只是改变改变量对应的内存空间中的内容。通俗的讲,可以把变量看作一个容器,创建一个变量就是构建一个容器,为变量赋值就是相当于在容器中放一个物品,为变量重新赋值就相当于改变容器中得物品。物品一直在变化但是容器不会变化。变量值可能在不断变化但是其对应得那块内存空间不会变,即内存地址不变。
func main(){
a := 43
fmt.Println(&a)//0xc00000a0b8
a = 5
fmt.Println(&a)//0xc00000a0b8
b := a
fmt.Println(a, b)//5 5
fmt.Println(&a, &b)//0xc00000a0b8 0xc00000a0f0
b = 3
fmt.Println(&b)//0xc00000a0f0
fmt.Println(a, b)//5 3
}
创建变量b得时候会在内存中重新开辟一块内存空间,b:=a是将a内存空间中得内容复制到b内存空间中去。在对b进行操作时a该什么样什么样不会影响b。变量a和b指向不同得内存空间。再对b重新赋值只是改变b得内存空间中得内容,b指向得内存地址不会改变。
2、指针变量
- 指针变量指向一个值的内存地址。
- 使用&+变量名 返回值就是一个指针类型。
- 使用var 变量名 *类型 声明一个指针类型变量。
- 声明指针不会开辟内存地址,只是准备要指向内存某个空间,而声明变量会开辟内存地址,准备存放内容。所以指针类型变量都是把一个变量的地址赋值给指针变量。
- 使用*+指针能够获取内存地址中得值,所以*+指针就和直接使用变量是相同得。
- 应用指针可以实现多个地方操作同一个内存地址得值(再方法参数应用指针较多)。
a := 123
var point *int //声明一个int类型的指针变量point,只是声明现在指针没有指向任何内存空间,也称为空指针
point = &a//将变量a的地址赋值给指针变量point,即point指向a所在的内存空间,&a也是一个指针类型
fmt.Println(point, &a)//0xc00006e090 0xc00006e090=>point等价于&a都是内存空间的地址
fmt.Println(*point, a)//123 123=>*point等价于a——*point表示获取内存地址中的值
*point = 34//改变内存空间中的数据,将123替换为34
fmt.Println(*point, a)//34 34 a和*point指向同一块内存空间,所以都是34
fmt.Println(point, &a)//0xc00006e090 0xc00006e090
3、空指针
- 指针的目的就是指向内存中的一块地址。
- 声明指针后,指针不会指向任何一块内存地址,所以此时指针是空的,go语言中空用nil表示。
var a *int
fmt.Println(a)//<nil>
fmt.Println(a==nil)//true
4、New函数介绍
- 在3中学习了指针,每次创建一个指针必须要再额外创建一个变量,操作比较麻烦。
- 可以通过new函数直接创建一个类型的指针:变量名 := new(类型)
- 使用new函数创建的指针已有指向,即不是空指针,可以使用 *指针变量 对该指针变量直接进行赋值
- var 指针变量名 *类型 方式声明的指针变量声明时为空指针且不可直接被赋值
var x *int //声明指针后,指针不指向任何一块内存地址,此时指针是空的 fmt.Println(x) //<nil> //var声明的指针变量不能直接赋值 panic: runtime error: invalid memory address or nil pointer dereference //[signal 0xc0000005 code=0x1 addr=0x0 pc=0x49a7d0] *x = 453 a := new(int) //使用new函数创建的指针变量不是空指针 fmt.Println(a) //0xc00000a0b8 *a = 124 fmt.Println(*a)//124