Go中指针的介绍和使用

背景

指针是什么出现的意义是什么呢?
假设所有语言中都没有指针, 无论是显式的还是隐式的.
那么所有的变量传递都只能通过值Copy的方式了, 如果对象比较大的话, 就会比较浪费空间和性能. 如果还要求对传入的数据进行修改, 还需要将数据返回回去, 就变得比较复杂.
指针的出现就完美的解决了这些问题

简介

Go 是一门支持指针的编程语言,与其他编程语言的指针类似,Go 指针指向的是一个内存地址,可以通过指针间接访问和修改关联的变量。Go 指针还具有许多与其他编程语言不同的特性,下面我们来详细了解一下 Go 指针的相关知识。

指针的声明

在 Go 中,指针的声明与其他变量一样,只需要在变量名前面添加 * 符号即可,例如:

var ptr *int // 声明一个 int 类型的指针

在这个例子中,我们声明了一个名为 ptr 的指针,该指针指向 int 类型的变量,此时该指针的值为 nil

指针还可以使用取地址操作符 & 来获取变量的地址,例如:

var a int = 10 // 声明一个 int 类型的变量
var ptr *int = &a // 声明一个 int 类型的指针,并将其初始化为变量 a 的地址

在这个例子中,我们声明了一个名为 a 的 int 类型的变量,并使用 & 运算符获取其地址,然后将该地址赋值给 ptr 指针变量。

指针的间接引用

在 Go 中,指针变量可以通过 * 符号进行间接引用,从而访问它所指向的变量的值。例如:

var a int = 10 // 声明一个 int 类型的变量
var ptr *int = &a // 声明一个 int 类型的指针,并将其初始化为变量 a 的地址
fmt.Println(*ptr) // 输出 ptr 所指向的变量 a 的值,即 10

在这个例子中,我们声明了一个名为 a 的 int 类型的变量,并使用 & 运算符获取其地址并赋值给 ptr 指针变量。然后我们使用 * 符号对指针进行间接引用,即可输出该指针所指向的变量 a 的值。

指针的空值

在 Go 中,指针变量的空值为 nil,它表示指针变量没有关联到任何内存地址。我们可以使用 nil 来检测一个指针是否为空,例如:

var ptr *int // 声明一个 int 类型的指针变量
if ptr == nil {
    fmt.Println("ptr is null")
}

在这个例子中,我们声明了一个名为 ptr 的 int 类型的指针变量,并使用 nil 来检测它是否为空。由于这个指针变量没有关联到任何内存地址,所以输出的结果为 ptr is null

指向数组的指针

在 Go 中,我们可以使用指针来指向数组的元素,例如:

var arr [3]int = [3]int{1, 2, 3} // 声明一个含有 3 个元素的 int 类型数组
var ptr *int = &arr[0] // 声明一个 int 类型的指针,并将其初始化为数组的第一个元素的地址
fmt.Println(*ptr) // 输出数组的第一个元素的值,即 1

在这个例子中,我们声明了一个名为 arr 的 int 类型的数组,并使用 & 运算符获取其第一个元素的地址并赋值给指针变量 ptr。然后我们使用 * 符号对指针进行间接引用,即可输出该指针所指向的数组的第一个元素的值。

指向结构体的指针

同样地,我们还可以使用指针来指向结构体的成员变量,例如:

type Person struct {
    name string
    age int
}

func main() {
    var p Person = Person{
        name: "Alice",
        age: 18,
    } // 声明一个 Person 类型的变量
    var ptr *Person = &p // 声明一个 Person 类型的指针,并将其初始化为变量 p 的地址
    fmt.Println((*ptr).name) // 输出指针所指向的变量 p 的 name 属性值,即 Alice
    fmt.Println(ptr.age) // 使用指针直接访问变量 p 的 age 属性值,即 18
}

在这个例子中,我们声明了一个名为 p 的 Person 类型的变量,并使用 & 运算符获取其地址并赋值给指针变量 ptr。然后我们使用 * 符号对指针进行间接引用,并访问该指针所指向的变量 p 的 name 属性值。还可以使用指针直接访问变量 p 的 age 属性值。

指针与函数

在 Go 中,函数与指针的关系非常密切,指针可以作为函数的参数或返回值传递。

我们可以使用指针参数来修改函数外部的变量,例如:

func addOne(ptr *int) {
    *ptr++
}

func main() {
    var a int = 10
    addOne(&a) // 使用指针参数修改变量 a 的值
    fmt.Println(a) // 输出修改后的变量 a 的值,即 11
}

在这个例子中,我们给函数addOne传入了一个名为 a 的 int 类型的指针, 并且进行了 ++ 操作, 发现其实结果作用于了main 里面的 a

Go语言指针小结

指针是Go语言中一个重要的概念,它可以方便地进行内存读写以及操作复杂数据类型。Go语言中的指针使用简单并且安全,需要注意的是,在使用指针时必须确保指针变量有指向有效的内存地址,否则会引发运行时错误。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/668.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分享几个常用的运维 shell 脚本

今天咸鱼给大家分享几个不错的 Linux 运维脚本,这些脚本中大量使用了 Linux 的文本三剑客: awkgrepsed 建议大家这三个工具都要了解并最好能够较为熟练的使用 根据 PID 显示进程所有信息 根据用户输入的PID,过滤出该PID所有的信息 #! /b…

春分策划×运维老王主讲:CMDB数据运营精准化公开课启动报名啦!

『CMDB数据运营精准化』 公开直播课 要来了! 👆扫描海报二维码,预约直播 CMDB似乎是运维中永恒的老话题。 提到CMDB很多人都是又爱又恨,爱的是它给我们提供了一个美好的未来,有了CMDB我们可以解决诸多运维中的难题。…

常见的Web安全漏洞:SYN攻击/CSRF/XSS

一、SYN攻击(属于DOS攻击) 什么情况下被动方出现SYN_RCVD状态?(flood攻击服务) 客户伪造 ip 端口, 向服务端发送SYN请求。完成2次握手,第三次服务端 等待客户端ACK确认,但由于客户不存在服务端一直未收到确认&#…

Rockchip RV1126 模型部署(完整部署流程)

文章目录1、芯片简介2、部署流程简述3、开发环境配置(RKNN-Toolkit)3.1、软件安装测试3.2、示例代码解析4、开发环境配置(RKNN-NPU)4.1、源码结构4.2、 编译源码4.3、源码解析4.4、芯片端运行5、量化算法解析1、芯片简介 环境概述…

动态矢量瓦片缓存库方案

目录 前言 二、实现步骤 1.将数据写入postgis数据库 2.将矢量瓦片数据写入缓存库 3.瓦片接口实现 4.瓦片局部更新接口实现 总结 前言 矢量瓦片作为webgis目前最优秀的数据格式,其主要特点就是解决了大批量数据在前端渲染时出现加载缓慢、卡顿的问题&#xff0…

Spark SQL支持DataFrame操作的数据源

DataFrame提供统一接口加载和保存数据源中的数据,包括:结构化数据、Parquet文件、JSON文件、Hive表,以及通过JDBC连接外部数据源。一个DataFrame可以作为普通的RDD操作,也可以通过(registerTempTable)注册成…

Python 四大主流 Web 编程框架

目前Python的网络编程框架已经多达几十个,逐个学习它们显然不现实。但这些框架在系统架构和运行环境中有很多共通之处,本文带领读者学习基于Python网络框架开发的常用知识,及目前的4种主流Python网络框架:Django、Tornado、Flask、Twisted。 …

树的前中后序的Morris遍历

目录 一.Morris遍历 1.什么是Morris遍历 2.基本思想 3.Morris遍历的优点和缺点 4.知识回顾----二叉树的线索化 二.中序Morris遍历 1.中序Morris遍历的分析 2.中序Morris遍历的思路 3.具体的代码实现 三.前序Morris遍历 1.前序Morris遍历的思路 2.具体的代码实现 四…

【深度强化学习】(6) PPO 模型解析,附Pytorch完整代码

大家好,今天和各位分享一下深度强化学习中的近端策略优化算法(proximal policy optimization,PPO),并借助 OpenAI 的 gym 环境完成一个小案例,完整代码可以从我的 GitHub 中获得: https://gith…

【解决】elementui ——tooltip提示在循环中点击一个,同时显示多个的问题!

同时显示多个tooltip——效果图: 点击第一个二维码把循环el-card中所有的tooltip都触发了 解决后效果图: 只显示点击的当前tooltip 解决办法: 通过循环item中定义字段,进行控制tooltip显示隐藏 代码: 页面代码&am…

数仓建模—主题域和主题

主题域和主题 前面在这个专题的第一篇,也就是数仓建模—数仓初识中我们就提到了一个概念—主题,这个概念其实在数仓的定义中也有提到 数据仓库是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合,用于支持管理决策。 今天我们主要来探究一下,数仓的主题到底是…

SpringBoot:手写一个 SpringBoot Starter

声明:原文作者:yuan_404 文章目录1. 说明2 . 编写启动器3 . 新建项目测试自己写的启动器1. 说明 启动器模块是一个 空 jar 文件,仅提供辅助性依赖管理,这些依赖可能用于自动装配或者其他类库 命名归约: 官方命名&…

【LeetCode】1544. 整理字符串、LCP 44. 开幕式焰火

作者:小卢 专栏:《Leetcode》 喜欢的话:世间因为少年的挺身而出,而更加瑰丽。 ——《人民日报》 目录 1544. 整理字符串 LCP 44. 开幕式焰火 1544. 整理字符串 1544. 整理字符串 题目描述…

深度学习 Day26——使用Pytorch实现猴痘病识别

深度学习 Day26——使用Pytorch实现猴痘病识别 文章目录深度学习 Day26——使用Pytorch实现猴痘病识别一、前言二、我的环境三、前期工作1、设置GPU导入依赖项2、导入猴痘病数据集3、划分数据集四、构建CNN网络五、训练模型1、设置超参数2、编写训练函数3、编写测试函数4、正式…

Golang每日一练(leetDay0006)

目录 16. 最接近的三数之和 3Sum Closest ★★ 17. 电话号码的字母组合 Letter-combinations-of-a-phone-number ★★ 18. 四数之和 4Sum ★★ 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一…

shell-流程控制-3

条件判断 格式1:test 条件表达式 格式2:[ 条件表达式 ] 条件表达式前后都有空格 格式3:[[ 条件表达式 ]] 条件表达式前后都有空格,支持正则表达式 文件测试 格式:[ 操作符 文件 ] 文件测试常用参数 [rootlocalhost ~]# [[ -…

Java实现调用第三方相关接口(附详细思路)

目录1.0.简单版2.0.升级版2-1.call.timeout()怎么传入新的超时值2-2.timeout(10, TimeUnit.SECONDS)两个参数的意思,具体含义3.0.进阶版3-1.java.net.SocketTimeoutException: 超时如何解决4.0.终极版1.0.简单版 以下是一个使用 Java 实际请求“第三方”的简单示例代…

Java的二叉树、红黑树、B+树

数组和链表是常用的数据结构,数组虽然查找快(有序数组可以通过二分法查找),但是插入和删除是比较慢的;而链表,插入和删除很快(只需要改变一些引用值),但是查找就很慢&…

项目实战典型案例26——nacos的命名空间名称和id不一致带来的思考

nacos的命名空间名称和id不一致带来的思考一:背景介绍Nacos命名空间相关知识点思考总结一:背景介绍 项目用的naocs做的配置中心和服务发现。由于开发环境和本地环境使用的都是同一个命名空间,我们多个服务相互调用的时候,由于开发…

C语言/动态通讯录

本文使用了malloc、realloc、calloc等和内存开辟有关的函数。 文章目录 前言 二、头文件 三、主界面 四、通讯录功能函数 1.全代码 2.增加联系人 3.删除联系人 4.查找联系人 5.修改联系人 6.展示联系人 7.清空联系人 8.退出通讯录 总结 前言 为了使用通讯录时,可以…
最新文章