彻底学会Go指针--就要学习Go语言

栏目: C · 发布时间: 6年前

内容简介:写代码的时候,我们通过变量就可以操作存储在内存中的值,进行赋值、加减运算等。大家有没有想过,变量代表什么呢?其实,一个变量对应一段内存空间,这段空间就存储了该变量相对应类型的值。指针的值就对应变量的地址,只通过指针,就可以更新或者读取变量的值,而不需要用到变量名。上面这段代码,声明了通过上面一段话的解释,相信大家对指针有了比较清晰的认识:指针指向一个变量的内存地址。要想使用指针,必须先声明,格式如下:

写代码的时候,我们通过变量就可以操作存储在内存中的值,进行赋值、加减运算等。大家有没有想过,变量代表什么呢?其实,一个变量对应一段内存空间,这段空间就存储了该变量相对应类型的值。指针的值就对应变量的地址,只通过指针,就可以更新或者读取变量的值,而不需要用到变量名。

var i int = 10      //声明变量i,并初始化为10
var ptr *int = &i 
fmt.Println(ptr,*ptr)
// 0xc000018060 10  指针变量ptr存储的是i地址,*ptr对应指针指向的变量的值
*ptr = 12  				// i=12  更新指针指向的变量的值
fmt.Println(*ptr,i)		// 12 12
复制代码

上面这段代码,声明了 *int 类型的指针变量 ptr ,通过取址运算符 & 获得指向整型变量 i 的地址。可以说,指针 ptr 指向变量 i ,或者说 ptr 指针保存了变量 i 的地址。

指针声明

通过上面一段话的解释,相信大家对指针有了比较清晰的认识:指针指向一个变量的内存地址。要想使用指针,必须先声明,格式如下:

var var_name *var_type
// var_name 指针名称,var_type 指针所指向的变量的类型
复制代码
var i int = 10
str := "go"
var ip *int         // *int类型的指针
var pstr *string    // *string类型的指针
ip = &i
pstr = &str
fmt.Println(*ip,*pstr)     // 10 go
复制代码

注意: *int 类型的指针,说明该指针指向的一定是 int 类型的变量, *string 类型也类似。

str := "go"
var ip *int
ip = &str  // 编译不会通过
复制代码

*int 类型的指针,指向的变量若是 string 类型的,编译器编译的时候就会报错:

cannot use &str (type *string) as type *int in assignment
复制代码

如何使用指针

文章写到这里,关于如何使用指针,其实上文已经列出来了,主要经过三个步骤: 声明赋值访问 指针指向的变量的值

x,y := 1,"go"
var px *int = &x    	// 1、声明并初始化
var py = &y				// 2、省略指针类型,编译器自动判断
//px,py := &x,&y		// 3、使用 :=
fmt.Println(*px,*py) 	// 1 go   访问
复制代码

关于空指针

一个指针已声明而没有赋值时,称为空指针,为 nil 。任何类型的指针的零值都是 nil

var ip *int
fmt.Println(ip)							// nil
fmt.Printf("ip 的值为:%x", ip)			// ip 的值为:0
复制代码

如果 ip != nil 为真,那么p是指向某个有效变量。指针之间也是可以进行相等测试的,只有当它们指向同一个变量或全部是 nil 时才相等。

1、指向同一个变量 true
x,_ := 1,1
px,py := &x,&x
fmt.Println(px == py) 
 
2、指向不同变量 false
x,y := 1,1
px,py := &x,&y
fmt.Println(px == py)

3、两个nil指针 true
var px *int
var py *int
fmt.Println(px == py)
复制代码

指针作为函数参数使用

指针包含的是一个变量的地址,如果将一个指针作为参数传递给函数,就可以通过指针来更新变量的值。

func a(p *int){
	*p++
}

i := 10
fmt.Println(i)      // 10
a(&i);
fmt.Println(i)		// 11
复制代码

不常用的new函数

给大家介绍下 new 函数,内建的 new 函数也是一种创建变量的方法, new(type) 表示创建一个 type 类型的匿名变量,并初始化为 type 类型的零值,返回变量的地址,指针类型为 *type

p := new(int)   	// p, *int 类型, 指向匿名的 int 变量
fmt.Println(*p) 	// 0
*p = 2          	// 设置 int 匿名变量的值为 2
fmt.Println(*p) 	// 2
复制代码

new 函数创建变量和普通变量声明语句方式创建变量没有什么区别,除了不需要声明一个临时变量的名字外。 下面的两个函数有着相同的行为: 创建变量,并返回变量地址

func newA() *int {
    return new(int)
}
func newB() *int {
    var i int
    return &i
}
复制代码

每次调用 new 函数都会返回新的变量的地址:

p := new(int)
q := new(int)
fmt.Println(p,q)   // 0xc000018060 0xc000018068
复制代码

new 函数使用的比较少,不过觉得挺有意思的,就在这给大家分享下!实际编程,多的还是使用具体类型创建变量,毕竟更方便,是吧!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

垃圾收集

垃圾收集

琼斯 / 谢之易 / 人民邮电出版社 / 2004-4-1 / 45.00元

书围绕着动态内存自动回收的话题,介绍了垃圾收集机制,详细分析了各种算法和相关技术。 本书共12章。第1章首先介绍计算机存储器管理的演化和自动内存回收的需求,并引入了本书所使用的术语和记法。第2章介绍了3种“经典”的垃圾收集技术:引用计数(reference counting)、标记-清扫(mark-sweep)和节点复制(copying)。 随后的4章更详细地讨论了上述这些垃圾收集方式......一起来看看 《垃圾收集》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具