一篇文章带你了解Go语言基础之指针

开发 后端
作为21世纪的C语言,Go可能多方面思考,最终还是保留了指针。但是要比C语言指针简单很多,一起来看看叭。

[[351627]]

前言

Hey,大家好呀,我是星期八

作为21世纪的C语言,Go可能多方面思考,最终还是保留了指针。

但是要比C语言指针简单很多,一起来看看叭。

引言

因为Go语言是类C语言,所以为了提高效率,仍然保留了指针。

但是如果没有接触过指针,可能学起来指针需要多多思考一下了。

指针通常情况下,也被称为小白劝退神奇。

基本类型指针的理解

先看这两行代码。

  1. var n1 int = 666 
  2. fmt.Println(n1)//结果:666 
  3. fmt.Printf("%p\n",n1)//结果:%!p(int=666),说明不是一个地址,就是一个值 

内存分布图如下。

再看看这样两行代码,这里用到了&。

  1. var n1 int = 1 
  2. //表示取n1的地址 
  3. fmt.Println(&n1)//结果:0xc00000a0b8 
  4. fmt.Printf("%p\n",&n1)//结果:0xc00000a0b8 

如图所示。

如果这两个能理解,恭喜你,指针已经会了一半了。

引用类型指针的理解

先看这样的代码。

  1. var studentList = []string{"张三", "李四"}//一个切片 
  2. fmt.Println(studentList)        //结果:[张三 李四] 
  3. fmt.Printf("%p\n", studentList) //结果:0xc0000044a0 
  4. //去地址 
  5. fmt.Printf("%p\n", &studentList) //结果:0xc0000044a0 

内存分布图如下。

值类型和引用类型

值类型

在Go中,值类型主要有。

int,float,bool,string,数组,struct(结构体)

内存分布大致如下。

注:像字符串,数组,结构体这些属于连续存储,变量指向的是它们的第一个地址,剩下的会根据长度计算。

引用类型

在Go中,引用类型主要有。

切片(slice),map,管道(chan)

内存分布大致如下。

栈内存和堆内存的区别

栈内存在存储上,只能存一些简单的东西,比如数字了,字符了,浮点数了之类的,但是栈内存分配的内存程序员不用回收,由系统自己回收,并且性能很高。

堆内存在存储上就比较丰富了,随便存,像map,随便塞,但是堆内存分配的内存需要程序员自己回收,典型例子,C++,如果语言由GC由GC回收,性能稍弱那么一点点点....,但是人家能随便存啊,多随便。

&和*的意思

&叫做取地址符。

*叫做收地址符吧。

示例

  1. var c *int//*int是一个整体,说明c这个变量只能接收int类型的 

*int是一个整体,表示c这个变量只能接收int类型的地址。

代码

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. func main() { 
  6.     var c *int 
  7.     var d int = 1 
  8.     //c = d//错误需要的是d的地址 
  9.     c = &d 
  10.     fmt.Println(c) 

执行结果。

可以看到打印的也是一个地址,但是内存图还是基本类型图。

如果要打印c的值,直接*c就好了,取得就是地址里面对应得值了。

  1. fmt.Println(*c) 

关于函数

我们一直在强调,操作只会操作栈上面的值,函数同理。

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. func say1(x int) { 
  6.     //x int 相当于隐藏了一行代码 
  7.     //隐藏的代码时 var x int = x,一定要记住这个 
  8.     fmt.Printf("say1:%p\n", x) 
  9. func say2(x *int) { 
  10.     //隐藏的代码是 var x *int = x,x是一个地址 
  11.     fmt.Printf("say2:%p\n", x) 
  12. func say3(x []int) { 
  13.     //隐藏的代码是 var x []int = x,因为x是引用类型,所以x是一个地址 
  14.     fmt.Printf("say3:%p\n", x) 
  15. func main() { 
  16.     say1(1)//栈上面是1,所以传进去就是1 
  17.     var x1 = 1 
  18.     say2(&x1)//say只能接收整数地址 
  19.     var x2 = []int{1, 1} 
  20.     say3(x2)//x2是引用类型,所以传进去的时候就是地址,栈上面的就是地址 

执行结果。

总结

上述我们主要讲述了基本类型指针和引用类型指针,也叫做值类型和引用类型,并且画出了值类型和引用类型内存的本质区分图,后来又讲了&和*的区别,还有函数传参的本质是什么,希望对大家的学习有帮助。

如果在操作过程中有任何问题,记得下面留言,我们看到会第一时间解决问题。

本文转载自微信公众号「Go语言进阶学习」,可以通过以下二维码关注。转载本文请联系Go语言进阶学习公众号。

 

责任编辑:武晓燕 来源: Go语言进阶学习
相关推荐

2020-11-05 09:58:16

Go语言Map

2022-02-16 10:03:06

对象接口代码

2020-10-22 08:33:22

Go语言

2020-12-09 09:59:32

Go语言技术

2020-10-25 07:33:13

Go语言

2022-04-27 10:01:43

切片Go封装

2020-10-23 08:38:19

Go语言

2020-12-30 09:04:32

Go语言TCPUDP

2020-12-27 10:15:44

Go语言channel管道

2021-10-09 07:10:31

Go语言基础

2021-10-30 10:43:04

语言Go函数

2021-11-03 10:02:07

Go基础函数

2020-12-07 05:59:02

语言Go接口

2021-09-29 10:00:07

Go语言基础

2021-10-13 10:00:52

Go语言基础

2020-10-22 11:15:47

Go语言变量

2021-10-16 10:17:51

Go语言数据类型

2020-12-23 08:39:11

Go语言基础技术

2021-02-20 10:06:14

语言文件操作

2021-01-13 08:40:04

Go语言文件操作
点赞
收藏

51CTO技术栈公众号