Go语言应该什么情况使用指针


Posted in Golang onJuly 25, 2021

什么是指针

我们都知道,程序运行时的数据是存放在内存中的,每一个存储在内存中的数据都有一个编号,这个编号就是内存地址。我们可以根据这个内存地址来找到内存中存储的数据,而内存地址可以被赋值给一个指针。我们也可以简单的理解为指针就是内存地址。

指针的声明和定义

在Go语言中,获取一个指针,直接使用取地址符&就可以。
示例:

func main() {
  name := "微客鸟窝"
  nameP := &name //取地址
  fmt.Println("name变量值为:", name)
  fmt.Println("name变量的内存地址为:", nameP)
}
//运行结果:
//name变量值为: 微客鸟窝
//name变量的内存地址为: 0xc00004e240

nameP 指针的类型是 *string
Go语言中,*类型名表示一个对应的指针类型

 

变量 内存中数据 内存地址
name := "微客鸟窝" 微客鸟窝 0xc00004e240
nameP := &name 0xc00004e240 0xc00004e360

从上面表格可以看到:

  • 普通变量 name 的值是微客鸟窝,存放在内存地址为 0xc00004e240 的内存中
  • 指针变量 namep 的值是普通变量的内存地址 0xc00004e240
  • 指针变量 nameP 的值存放在 内存地址为 0xc00004e360 的内存中
  • 普通变量存的是数据,指针变量存的是数据的地址

var 关键字声明

我们也可以使用 var 关键字声明

var nameP *string
nameP = &name

new 函数声明

nameP := new(string)
nameP = &name

可以传递类型给这个内置的 new 函数,它会返回对应的指针类型。

指针的操作

这里强调一下:
指针变量是一个变量,这个变量的值是指针(内存地址)!
指针变量是一个变量,这个变量的值是指针(内存地址)!
指针变量是一个变量,这个变量的值是指针(内存地址)!

获取指针指向的值:

只需要在指针变量钱加 * 号即可获得指针变量值所对应的数据:

nameV := *nameP
fmt.Println("nameP指针指向的值为:",nameV) //nameP指针指向的值为: 微客鸟窝

修改指针指向的值:

*nameP = "三水点靠木" //修改指针指向的值
fmt.Println("nameP指针指向的值为:",*nameP)
fmt.Println("name变量的值为:",name)
//运行结果:
//nameP指针指向的值为: 三水点靠木
//name变量的值为: 三水点靠木

我们发现nameP 指针指向的值被改变了,变量 name 的值也被改变了
因为变量 name 存储数据的内存就是指针 nameP 指向的内存,这块内存被 nameP 修改后,变量 name 的值也被修改了。

通过 var 关键字直接定义的指针变量是不能进行赋值操作的,因为它的值为 nil,也就是还没有指向的内存地址

//错误示例
var intP *int
*intP = 10  //错误,应该先给分配一块内存,内存地址作为变量 intP 的值,这个内存就可以存放 10 了。

//应该使用
var intP *int  //声明int类型的指针变量 intP
intP = new(int) // 给指针分配一块内存
*intP = 66 
fmt.Println(":::",intP)  //::: 0xc0000ac088
fmt.Println(*intP) //66
//简短写法
var intP := new(int)
*intP=66

指针参数

当给一个函数使用指针作为参数的时候,就可以在函数中,通过形参改变实参的值:

func main() {
 name := "无尘"
 modify(&name)
 fmt.Println("name的值为:",name)
}
func modify(name *string)  {
 *name = "wucs"
}
//运行结果:
//name的值为: wucs

指针接收者

  • 如果接收者类型是 map、slice、channel 这类引用类型,不使用指针;
  • 如果需要修改接收者,那么需要使用指针;
  • 如果接收者是比较大的类型,可以考虑使用指针,因为内存拷贝廉价,所以效率高。

什么情况下使用指针

  • 不要对 map、slice、channel 这类引用类型使用指针;
  • 如果需要修改方法接收者内部的数据或者状态时,需要使用指针;
  • 如果需要修改参数的值或者内部数据时,也需要使用指针类型的参数;
  • 如果是比较大的结构体,每次参数传递或者调用方法都要内存拷贝,内存占用多,这时候可以考虑使用指针;
  • 像 int、bool 这样的小数据类型没必要使用指针;
  • 如果需要并发安全,则尽可能地不要使用指针,使用指针一定要保证并发安全;
  • 指针最好不要嵌套,也就是不要使用一个指向指针的指针,虽然 Go 语言允许这么做,但是这会使你的代码变得异常复杂。

到此这篇关于Go语言应该什么情况使用指针的文章就介绍到这了,更多相关Go语言使用指针内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木! 

Golang 相关文章推荐
golang中的空slice案例
Apr 27 Golang
Golang 实现超大文件读取的两种方法
Apr 27 Golang
goland 清除所有的默认设置操作
Apr 28 Golang
Go语言中break label与goto label的区别
Apr 28 Golang
解决Goland 同一个package中函数互相调用的问题
May 06 Golang
Go 自定义package包设置与导入操作
May 06 Golang
浅谈Go语言多态的实现与interface使用
Jun 16 Golang
Go 语言下基于Redis分布式锁的实现方式
Jun 28 Golang
Go语言基础知识点介绍
Jul 04 Golang
Go语言应该什么情况使用指针
Jul 25 Golang
Golang使用Panic与Recover进行错误捕获
Mar 22 Golang
Go微服务项目配置文件的定义和读取示例详解
Jun 21 Golang
基于Go语言构建RESTful API服务
Jul 25 #Golang
go goroutine 怎样进行错误处理
Jul 16 #Golang
go开发alertmanger实现钉钉报警
Jul 16 #Golang
K8s部署发布Golang应用程序的实现方法
Jul 16 #Golang
入门学习Go的基本语法
Jul 07 #Golang
golang中字符串MD5生成方式总结
Jul 04 #Golang
golang fmt格式“占位符”的实例用法详解
Jul 04 #Golang
You might like
PHP语法速查表
2006/12/06 PHP
个人写的PHP验证码生成类分享
2014/08/21 PHP
PHP的Yii框架的基本使用示例
2015/08/21 PHP
PHP空值检测函数与方法汇总
2017/11/19 PHP
PHP xpath()函数讲解
2019/02/11 PHP
javascript中的缓动效果实现程序
2012/12/29 Javascript
变量声明时命名与变量作为对象属性时命名的区别解析
2013/12/06 Javascript
前台js对象在后台转化java对象的问题探讨
2013/12/20 Javascript
javascript计算用户打开网页的停留时间
2014/01/09 Javascript
js中精确计算加法和减法示例
2014/03/28 Javascript
struts2+jquery组合验证注册用户是否存在
2014/04/30 Javascript
js window对象属性和方法相关资料整理
2015/11/11 Javascript
基于javascript代码实现通过点击图片显示原图片
2015/11/29 Javascript
JavaScript必知必会(十) call apply bind的用法说明
2016/06/08 Javascript
jQuery实现鼠标经过时高亮,同时其他同级元素变暗的效果
2016/09/18 Javascript
为Jquery EasyUI 组件加上清除功能的方法(详解)
2017/04/13 jQuery
vue几个常用跨域处理方式介绍
2018/02/07 Javascript
Koa 使用小技巧(小结)
2018/10/22 Javascript
深入浅析vue-cli@3.0 使用及配置说明
2019/05/08 Javascript
python爬虫之BeautifulSoup 使用select方法详解
2017/10/23 Python
Python给你的头像加上圣诞帽
2018/01/04 Python
PyQt实现界面翻转切换效果
2018/04/20 Python
对python中类的继承与方法重写介绍
2019/01/20 Python
网易有道2017内推编程题 洗牌(python)
2019/06/19 Python
关于Pytorch MaxUnpool2d中size操作方式
2020/01/03 Python
keras获得某一层或者某层权重的输出实例
2020/01/24 Python
利用Python计算KS的实例详解
2020/03/03 Python
搭建pypi私有仓库实现过程详解
2020/11/25 Python
CSS3中的弹性布局em运用入门详解 1em等于多少像素
2021/02/08 HTML / CSS
优秀员工自荐书
2013/12/19 职场文书
节能环保口号
2014/06/12 职场文书
2014年环保局工作总结
2014/12/11 职场文书
罚站检讨书
2015/01/29 职场文书
人事聘任通知
2015/04/21 职场文书
详解Python 3.10 中的新功能和变化
2021/04/28 Python
【海涛七七解说】DCG第二周:DK VS 天禄
2022/04/01 DOTA