指针
概述
- 指针是存储另一个变量的内存地址的变量
- 变量是一种使用方便的占位符,变量都指向计算机的内存地址
- 一个指针变量可以指向任何一个值的内存地址
- 获取变量的地址
Go语言的取地址符&,一个变量前使用&,会返回该变量的内存地址。
func main(){
a := 110
fmt.Printf("变量的地址:%x\n",&a)
}
- 指针特点
- 指针不能运算(不同于c语言)
- Go语言中如果对指针进行运算会报错
声明指针
*T是指针变量的类型,它指向T类型的值。
var 指针变量名 *指针类型
- *号用于之sing变量是一个指针
- var ip *int //指向整型的指针
- var fp *float64 //指向浮点型的指针
指针使用流程
- 定义指针变量
- 为指针变量赋值
- 访问指针变量中指向地址的值
- 获取指针的值:在指针类型的变量前加上*号来获取指针所指向的内容
空指针
GO 空指针
- 当一个指针被定义后没有分配到任何变量是,它的值为nil
- nil指针也称为空指针
- nil在概念上和其他语言null,NULL一样,都指代零值或空值
- 一个指针变量通常缩写为ptr
空指针判断
if(ptr != nil)
if(ptr == nil)
指针数组
指针数组:就是元素为指针类型的数组。
- 定义一个指针数组
- var ptr [3]*string
- 有一个元素个数相同的数组,将该数组中每个元素的地址赋值给该指针数组。也就是说该指针数组与某一个数组完全对应
- 可以通过*指针变量获取到该地址所对应的数值
双重指针
- 如果一个指针变量存放的有事另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。
当定义一个指向指针的指针变量是,第一个指针存放第二个指针的地址,第二个指针存放变量的地址 - 声明格式如下
```go
var ptr **int
//以上指向指针的指针变量为整形
//访问指向指针的指针变量值需要使用两个*号
```
```
函数参数传递
函数如果使用参数,该参数变量称为函数的形参。形参就像定义在函数体内的局部变量。调用函数,可以通过两种方式来传递参数:值传递和引用传递。
值传递
概念
值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改将不会影响到原内容数据。
- 默认情况下,Go语言使用的是值传递,即在调用过程中不会影响到原内容数据
- 每次调用函数,都将实参拷贝一份在传递到函数中。每次拷贝一份,性能就下降了。GO语言中使用指针和值传递配合避免了性能降低。
引用传递
概念
引用传递:是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到原内容数据
- 严格来说Go语言只有值传递一种传参方式,Go语言没有引用传递的
- Go语言中可以借助指针来实现引用传递的效果。函数参数使用指针,传参时其实是在拷贝一份指针参数,也就是拷贝了一份变量地址
- 函数的参数如果是指针,当函数调用时,虽然参数仍然是按拷贝传递的,但拷贝仅仅是个指针(一个内存地址),这样就可以减少实参拷贝造成的内存浪费,时间开销,性能降低的情况
作用
- 传指针使得多个函数能操作同一个对象
- 传指针更轻量级(8bytes),只需要传内存地址。如果参数是非指针参数,那么值传递的过程中,每次在拷贝上面就会花费较多的系统开销。所以当要传递大的结构体的时候,用指针是一个明智的选择
- Go语言中的slice,map,channel类型的实现机制都是类似指针,所以可以直接传递,而不必取地址后传递指针