指针的英文名是pointer,意思是某种事物的标识,比如路面上的直行标识,当我们做笔记的时候,给某个词语做解释的时候会用到箭头标识,景区的厕所往往有男厕所和女厕所的标识。无论标识是怎样的形状或用语,目的都是帮助人们更快的找到自己的目标。
指针有2个基本元素或内容:
-
指针地址
-
指针指向的值
下面用具体的例子来看看这2个东西
var name = "lizi"
//用 & 来获取name这个变量所对应的地址,或者说这个变量存放的内存的位置/编号
addrOfName = &name
//通过地址来获取变量的值,用*来获取地址对应的值
var nameValue = *addrOfName
可以看得出,变量和它的指针,或者更加形象的说,它的内存地址是形影不离的,并且是可以互相理解的,因为可以通过变量获取到它的内存地址,也可以通过它的内存地址获取到它的值。
那知道了指针之后,我们似乎只能对他们进行查询操作,怎么进行数据的修改呢?因为数据的修改在程序中也是经常需要的,事物往往会随着时间表现出某些层面的变化,比如人的年龄,这几天的天气,一句话在不同语境下的含义也会有所不同。
下面看2个例子:
//定义一个修改年龄的函数
func editAge(age int){
age = 10
}
//定义一个修改年龄 函数,不同的是传入的变量的类型是指针类型
//说指针类型不好理解,可以换成内存地址类型
//表示这个变量是用来存放内存地址的,而不是他 对应的值
func editName2(age *int) {
*age = 10
}
从这2个例子看得出来go的函数的参数是值拷贝的,所以第一个函数的作用只是改变了副本变量的值,没有去改变原变量的值;要改变原变量的值,需要通过先获取到它的内存地址,通过内存地址取值之后再赋予它新的值才可以改变原来的变量的值。
为什么说是从简的指针呢?因为在C,C++这类语言对指针的使用招数很多,用多了,反而让程序不易理解;而go里面的指针不能参与运算,就只有获取变量的内存地址和通过内存地址去获取对应的值。这种设计似乎很类似人们生活当中对许多标识的普遍认知和常见用途。
总结 一个好的标识,不需要让人们花太多时间去思考它的作用,就像一个好的名称不需要我们去像学者研究它的定义。标识的出现暗合了用空间换时间的普遍规律。