Go指针
指针:
指针是一种数据类型,用来存储值的内存地址,为了便于理解,我们也可以把指针理解为内存地址。
指针类型只占用内存4个或8个字节
指针类型变量也需要一块内存空间存储值,指针变量的值就是它所指向数据的内存地址,而普通变量的值就是存放的具体数据。
不同的指针类型变量之间无法互相赋值
Go语言指针:
区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针。Go语言中的操作非常简单,只需要记住两个符号:&(取地址)和*(根据地址取值)
Go语言中的函数传参都是值拷贝,当我们想要修改某个变量的时候,我们可以创建一个指向该变量内存地址的指针变量。传递数据使用指针,而无需拷贝数据
每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。go语言中取地址符是 & ,放到一个变量前使用就会返回这个变量的内存地址
在 Golang 语言中,类型名称前加 * 表示该类型是指针类型。
Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:*int、*int64、*string等
1)什么是指针?
一个指针变量指向了一个值的内存地址
类似于变量和常量,在使用指针时需要先声明指针
2)声明指针
在Go语言中,指针定义有三种方式:
①:使用取地址符 & 获取变量的指针(内存地址)
②:使用var关键字声明指针变量,使用var关键字声明的变量不能直接赋值和取值,因为它还没有内存地址,它的值是nil
var var_name *var_type 如:var a *int //一个指向整形的指针
var_type为指针类型,var_name为指针变量名,*号用于指定变量是作为一个指针
③:使用内置的new函数来声明指针类型的变量,new函数接收一个参数,可以传递类型给它,返回值是传递类型的指针类型
3)指针使用流程:
①:定义指针变量
②:为指针变量赋值
③:访问指针变量中指向地址的值(在指针类型前面加上 * 号来获取指针所指向的内容)
var ptr *string // 定义指针
ptr = &a // 为指针赋值
b := *ptr // 访问指针的值
指针操作:
指针操作包括取值和修改
取值:就是获取指针指向的值,只需在指针变量前加 *
修改:就是修改指针指向的值,需要注意的是使用var关键字声明的指针变量不能直接赋值和取值,因为它还没有分配内存,它的值为nil,可以使用内置函数new给它分配内存。
4)go空指针:
当一个指针被定义后没有分配任何变量时,它的值为nil,nil指针也称为空指针
nil在概念上和其他语言的null,None一样,都指代零值或空值
5)指针作为函数参数
Go语言允许向函数传递指针,只需要在函数定义的参数上设置为指针类型即可。
在Go语言中,函数传递参数只有值传递,传递的实参都是参数原始值的拷贝副本,所以我们传递值类型的参数时,修改参数的值,原始数据不会被修改。
但是,如果是指针类型的参数,修改参数的值,原始数据也会被修改,原因是指针类型的参数存储的是内存地址,并且和实参的内存地址相同
var a int = 100 var b int= 200 swap(&a, &b); func swap(x *int, y *int) { var temp int temp = *x /* 保存 x 地址的值 */ *x = *y /* 将 y 赋值给 x */ *y = temp /* 将 temp 赋值给 y */ }
6)指针接收者
在Go语言中,定义一个方法,接收者可以是值类型和指针类型,二者都可以调用方法,因为Golang编译器会自动转换,所以二者是等价的。
那么,应该在什么时候使用指针接收者呢?
①:如果需要修改接收者,可以使用指针修改指针指向数据的值
②:如果接收者是非map、slice、channel类型(因为这三种类型本身就是引用类型),并且数据比较大,可以使用指针来节省内存
END.