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 相关文章推荐
go 原生http web 服务跨域restful api的写法介绍
Apr 27 Golang
golang goroutine顺序输出方式
Apr 29 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
解决go在函数退出后子协程的退出问题
Apr 30 Golang
Golang之sync.Pool使用详解
May 06 Golang
go语言中fallthrough的用法说明
May 06 Golang
聊聊golang中多个defer的执行顺序
May 08 Golang
Go语言基础函数基本用法及示例详解
Nov 17 Golang
Go语言的协程上下文的几个方法和用法
Apr 11 Golang
Go语言grpc和protobuf
Apr 13 Golang
golang的文件创建及读写操作
Apr 14 Golang
Go语言编译原理之变量捕获
Aug 05 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实现多维数组中每个单元值(数字)翻倍的方法
2015/02/16 PHP
JavaScript学习点滴 call、apply的区别
2010/10/22 Javascript
5个可以帮你理解JavaScript核心闭包和作用域的小例子
2014/10/08 Javascript
20条学习javascript的编程规范的建议
2014/11/28 Javascript
jQuery实现将页面上HTML标签换成另外标签的方法
2015/06/09 Javascript
jquery显示loading图片直到网页加载完成的方法
2015/06/25 Javascript
jquery插件tytabs.jquery.min.js实现渐变TAB选项卡效果
2015/08/25 Javascript
如何解决IONIC页面底部被遮住无法向上滚动问题
2016/09/06 Javascript
jQuery元素属性操作实例(设置、获取及删除元素属性)
2016/09/08 Javascript
jQuery实现输入框邮箱内容自动补全与上下翻动显示效果【附demo源码下载】
2016/09/20 Javascript
使用微信内嵌H5网页解决JS倒计时失效问题
2017/01/13 Javascript
Vue键盘事件用法总结
2017/04/18 Javascript
Angular 4依赖注入学习教程之InjectToken的使用(八)
2017/06/04 Javascript
nodejs mysql 实现分页的方法
2017/06/06 NodeJs
angularJs的ng-class切换class
2017/06/23 Javascript
使用vuex的state状态对象的5种方式
2018/04/19 Javascript
微信小程序全局变量GLOBALDATA的定义和调用过程解析
2019/09/23 Javascript
怎么理解wx.navigateTo的events参数使用详情
2020/05/18 Javascript
js 函数性能比较方法
2020/08/24 Javascript
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
[01:08:44]NB vs VP 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python下函数参数的传递(参数带星号的说明)
2010/09/19 Python
python应用程序在windows下不出现cmd窗口的办法
2014/05/29 Python
Django中模型Model添加JSON类型字段的方法
2015/06/17 Python
Python基于递归算法实现的走迷宫问题
2017/08/04 Python
Django 限制用户访问频率的中间件的实现
2018/08/23 Python
Python中利用LSTM模型进行时间序列预测分析的实现
2019/07/26 Python
pytorch1.0中torch.nn.Conv2d用法详解
2020/01/10 Python
美国存储和组织商店:The Container Store
2017/08/16 全球购物
史蒂夫·马登加拿大官网:Steve Madden加拿大
2017/11/18 全球购物
销售辞职报告范文
2014/01/12 职场文书
2015年度个人教学工作总结
2015/05/20 职场文书
保护地球的宣传语
2015/07/13 职场文书
接触艺术对孩子学习思维有益
2019/08/06 职场文书
利用python调用摄像头的实例分析
2021/06/07 Python
微软Win11有哪些隐藏功能? windows11多个功能汇总
2021/11/21 数码科技