Golang指针说明
Go语言的每种数据类型(比如:基本数据类型int系列、float系列、bool、string、数组和结构体struct,等...)都有对应的指针类型,形式为 *数据类型
比如:int 对应的指针就是 *int,float32 对应的指针就是 *float32,以此类推
在Golang中,获取变量的地址,用 & ,比如声明一个整型变量,输出它的地址:
var num int //声明一个变量
fmt.Println(&num) //获取变量 num 的地址

指针变量存的是一个地址,这个地址指向的空间存的才是值
这样理解:指针变量也是一个变量,它的类型是指针类型,它在内存中存储的值是所指向变量的地址,通过这个地址可直接操作指向的变量
演示声明一个指针变量:
var num int //声明一个变量
var ptr *int = &num //声明一个指针变量 ptr,值为变量 num 的地址
获取指针类型所指向的值,使用取值符号:* ,比如:
var num int = 10 //声明一个变量,类型是 int
var ptr *int = &num //声明一个指针变量,类型是 *int
fmt.Println(*ptr) //使用 *ptr 获取指针变量 ptr 指向的值

切记不要混淆
声明指针变量时使用:
变量名 *变量类型
使用指针变量时,不论读取或修改,都是:
*变量名
使用时若不在变量前加“*”,*int、*float64、*string... ,会输出指针所指向变量的地址,如:0xc0000120a0,*map、*struct等则会输出拼接了地址符的变量值,告诉你这是指针,其它都一样,如:&map[a:1 b:2 c:3]、&{Tom 18}
map指针
m := map[string]int{"a": 1, "b": 2, "c": 3} //声明 map 变量
var mm *map[string]int = &m //声明 map 指针变量
(*mm)["a"] = 111 //通过 map 指针修改 map 字段的值,注意写法,带 * 使用时,map 指针外的括号不能丢(*优先级较低)
mm["b"] = 222 //这种写法也可以,Go的底层会加上*
fmt.Println(m)
结构体指针,可通过 new 关键字或 & 符号初始化
//var u *User = &User{} //方式一
//var u *User = &User{"Tom", 18} //方式二
var u *User = new(User) //方式三,new(结构体)会得到一个结构体指针
//因为 u 是一个指针,因此标准的给字段赋值方式
(*u).Name = "Tom"
//有种简化写法,可以去掉指针变量前面的*,Go的设计者认为这样做,更符合程序员的使用习惯
//Go的编译器底层会对 u.Age = 18 进行处理,给 u 加上取值运算,转化为 (*u).Age = 18
//所以,(*u).Age 等价于 u.Age,前者为标准写法,后者为简化写法
u.Age = 18
fmt.Println("u =", *u)
实际演示案例

通过指针变量修改所指向的值
var num int = 10
var ptr *int = &num
*ptr = 20 //这里修改时,会看到num的值变化
fmt.Println(num) //20
案例演示

值类型和引用类型的使用特点:
值类型:变量直接存储值,内存通常在栈中分配
引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据,内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收。
下一篇:Golang标识符