【30天熟悉Go语言】6 Go 复杂数据类型之指针

news2024/11/18 5:54:51

文章目录

  • 一、前言
  • 二、数据类型总览
  • 三、指针
    • 1、特殊运算符& *
    • 2、内存角度来看指针
    • 3、使用指针修改数据
    • 4、指针使用的注意事项
    • 5、对比着看Java的引用类型
  • 三、总结

一、前言

在这里插入图片描述

Go系列文章:

  1. GO开篇:手握Java走进Golang的世界
  2. 2 Go开发环境搭建、Hello World程序运行
  3. 3 Go编程规约和API包
  4. 4 Go的变量、常量、运算符
  5. 5 Go 基本数据类型

Go专栏传送链接:https://blog.csdn.net/saintmm/category_12326997.html

二、数据类型总览

在这里插入图片描述

三、指针

和 C/C++ 中的指针不同,Go中的指针不能进行偏移和运算。它是一种类型指针,可以用于传递数据、对数据进行修改。

简单一点理解:一个指针类型的变量其实就是一个值的内存地址,我们可以通过这个变量的地址(指针)去访问 / 操作数据。

使用指针获取变量内存地址的语法格式:

ptr := &v
  • v 是被取内存地址的变量;
  • 变量ptr的类型为*T,即T的指针类型,*代表指针;变量ptr用于接收变量v的内存地址。
  • 基本数据类型(又叫值类型),都有对应的指针类型,形式为*数据类型
    • 比如:int的对应的指针为*intfloat32对应的指针类型为*float32,依次类推…

1、特殊运算符& *

在Go中 & 和 * 有特殊的用意:

  • & :返回变量的存储地址
  • *:指针取值,取指针变量对应的数值
func main() {
	var age int = 18
	fmt.Println("age对应的存储空间内存地址为:",&age)

	// 指针变量 ptr,指向age在存储空间的内存地址
	var ptr *int = &age
	// 指针变量的类型
	fmt.Printf("ptr类型为: %T\n", ptr)
	// ptr指向的内存地址
	fmt.Printf("ptr指向的内存地址为:%p\n", ptr)

	// ptr变量自身的内存地址
	fmt.Println("ptr变量自身存储的内存地址为:", &ptr)

	// 指针取值
	value := *ptr
	fmt.Println("ptr这个指针指向的具体数值为:", value)

	// 取值后的类型
	fmt.Printf("value type: %T \n", value)
}

控制台输出如下:
在这里插入图片描述

  • 变量ptr的类型为*int
  • ptr指针变量的值为指针地址(16进制的整数);
  • ptr的指针地址,为变量age的内存地址(0xc0000a6058);
  • ptr变量本身也需要一个内存地址(0xc0000ca020)进行存储
  • ptr变量的指针取值操作,获取到的值和类型为变量age的值和类型。

2、内存角度来看指针

普通变量:
在这里插入图片描述

使用var age int = 18声明一个age变量之后,实际在内存中为age变量开辟了一块空间,并且这个空间中存储的数值时18,内存空间会有一个唯一标识(内存地址)。

指针变量:

// 指针变量 ptr,指向age在存储空间的内存地址
var ptr *int = &age

// ptr指向的内存地址
fmt.Printf("ptr指向的内存地址为:%p\n", ptr)

// ptr变量自身的内存地址
fmt.Println("ptr变量自身存储的内存地址为:", &ptr)

在这里插入图片描述

使用var ptr *int = &age声明一个ptr指针变量之后,实际在内存中也为ptr变量开辟了一块空间,并且这个空间中存储的数值为age变量的内存地址(0xc0000a6058);ptr变临港在内存空间也会有一个唯一标识(内存地址:0xc0000ca020)。

3、使用指针修改数据

指针不只可以用来取值,也可以使用来修改值

var num int = 10
fmt.Println(num)
var ptr *int = &num
*ptr = 20
fmt.Println(num)

控制台输出:
在这里插入图片描述

上面介绍了*ptr为指针取值,这里呢,*ptr = ?则直接用于指针赋值,即修改指针地址的数据内容。

4、指针使用的注意事项

1> 指针变量接收的一定是地址值

// 这种方式不允许
var prt *int = num

2> 指针变量类型和相应数据的类型不可以不匹配

var num int = 10
fmt.Println(num)
// 这种方式不允许,ptr指针的类型应该为*int
var ptr *float32 = &num

解释:*float32 意味着指针指向的是float32类型的数据,但是&num对应的是int类型的数据,所以不可以这样操作。

5、对比着看Java的引用类型

Java也是按值传递,但针对引用类型,方法之间传递引用类型的变量实际传递的是变量的内存地址,通过这个变量我们可以直接操作相应类型在内存中的数据;

以下面的代码为例,在method b中修改了变量variable 的某一块数据,在method b 的上层方法method a中也是有感知的,因为它们共享同一块内存地址的数据。

public class Main {
    public static void main(String[] args) {
        a();
    }


    public static void a() {
        ClassA variable = new ClassA(18, "saint");
        System.out.println("进入method b 方法前:" + variable.toString());
        System.out.println("method a 中variable内存地址为:" + variable.hashCode());
        b(variable);
        System.out.println("进入method b 方法后:" + variable.toString());
    }

    public static void b(ClassA variable) {
        System.out.println("method b 中variable内存地址为:" + variable.hashCode());
        variable.setAge(28);
    }

    @Data
    @ToString
    static class ClassA {
        private Integer age;
        private String name;

        public ClassA() {
        }

        public ClassA(Integer age, String name) {
            this.age = age;
            this.name = name;
        }
    }
}

控制台输出:
在这里插入图片描述

如果在method b 中对变量variable进行了整体的重新赋值,则变量variable在method b中内存地址发生改变,与method b 上层方法method a中的内存地址不同了。即:它们不在共享同一块内存地址的数据,在method b中修改variable内部的值不会影响method a中的variable变量的数据。

public static void b(ClassA variable) {
    variable = new ClassA();
    System.out.println("method b 中variable内存地址为:" + variable.hashCode());
    variable.setAge(28);
}

在这里插入图片描述
在这里插入图片描述
从方法执行的堆栈信息来看,在method a中variable的内存地址为510,在method b中variable的内存地址为505。

三、总结

指针呢就是内存地址,类比理解为java中的引用类型。额外再记忆两个运算符、一个公式。

两个运算符:

  • & :取变量的存储地址
  • *:指针取值,取指针变量对应的数值

一个公式:

  • ptr := &v
    • v 是被取内存地址的变量;
    • 变量ptr用于接收变量v的内存地址。
    • 基本数据类型(又叫值类型),都有对应的指针类型,形式为*数据类型,比如:int的对应的指针为*int

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Zstack实习-基础知识总结归纳-待更新

什么是虚拟化? 虚拟化技术是一种将物理计算资源,如服务器、存储和网络等,转化成虚拟的逻辑资源的技术。通过虚拟化技术,可以将多个独立的操作系统运行在同一台物理计算机上,实现资源的共享,提高硬件的利用率…

C++那些事之项目篇Catch2

C那些事之项目篇Catch2 今天推荐一个值得学习的开源项目"Catch2" ,之前写过如何使用google的googletest编写单元测试,你会发现需要编译生成lib库,比较麻烦,而Catch2是一个Header only库,能够快速使用&#x…

Python3数据分析与挖掘建模(13)复合分析-因子关分析与小结

1.因子分析 1.1 探索性因子分析 探索性因子分析(Exploratory Factor Analysis,EFA)是一种统计方法,用于分析观测变量之间的潜在结构和关联性。它旨在确定多个观测变量是否可以归结为较少数量的潜在因子,从而帮助简化…

机器学习笔记 - 多实例学习(MIL)弱监督学习

一、多实例学习概述 多实例学习(MIL)是一种弱监督学习形式,其中训练实例被排列在称为袋的集合中,并为整个袋提供标签。这种方式越来越受到人们的关注,因为它自然适合各种问题,并允许利用弱标记数据。因此,它被应用于计算机视觉和文档分类等不同的应用领域。 多实例学习(…

【国产虚拟仪器】基于 ZYNQ的声发射采集系统方案

系 统 的 整 体 设 计 流 程 为 根 据 上 述 设 计 需 求 进 行 硬 件 设 备 的 选 型 并 搭 建 起 声 发 射 采 集 系 统 的 硬 件 平 台 , 在 该平 台 上 进行 声 发 射 采 集 板 卡 的 设 计 并 根 据 要求进行 上 位 机…

2023上半年的九个觉悟

‍觉悟,就是觉了、悟了。有时候,你看到一句话,突然就觉悟了。 一、资本主义的问题 “资本主义把我们都缩减成了一个东西:消费者” 因此,人人都成为资本家利诱、操控、围猎的对象。 同时,金钱成为全民的神&a…

【PHP】Wampserver启动时呈现黄色的解决方案

首先,我们可以进入服务查看WampServer的服务是哪几个没有开? 经观察上图发现: apache没有开启sql没有开启 如果你点击开启,将会出现报错信息,因为服务冲突 所以解决方式就是:关闭冲突服务,再次…

基于SpringBoot+Vue的校园台球厅人员与设备管理系统设计与实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

基于JavaWeb SSM mybatis 学生信息管理系统设计和实现以及文档报告

基于JavaWeb SSM mybatis 学生信息管理系统设计和实现以及文档报告 博主介绍:5年java开发经验,专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源…

想要更好地理解大模型架构?从计算参数量快速入手

编者按:要理解一种新的机器学习架构(以及其他任何新技术),最有效的方法就是从头开始实现它。然而,还有一种更简单的方法——计算参数数量。 通过计算参数数量,读者可以更好地理解模型架构,并检查…

LBP特征提取

文章目录 1 LBP原理及其扩展1.1 原始LBP1.2 圆形LBP1.3 旋转不变LBP1.4 Uniform Pattern LBP1.5 MB-LBP 2. 对于边缘点的处理3. LBP的Python应用4. LBPH算法及其应用4.1 LBPH算法原理4.2 LBPH识别应用 5. 源码仓库地址 LBP指局部二值模式,英文全称:Local…

3.1 基于配置文件整合SSM框架实现用户登录

一、基于XML配置方式整合SSM框架实现用户登录 1、创建数据库与表 (1)创建数据库 数据库simonshop,采用utf8mb4编码 (2)创建用户表 创建用户表t_user CREATE TABLE t_user (id int(11) NOT NULL AUTO_INCREMENT,u…

中国金融,如何向科技要答案?

一个科技初创公司,能否凭借科创成果及时获得信贷准入? 一个农民兄弟能否在春播时,获得精准的无抵押贷款;秋收时,通过银行App找到性价比最高的买家? 一家企业,能否通过其生产及交易信息获取线上融…

对话利星行汽车:合作圆满,对斯歌充分信任!

上海斯歌在利星行汽车的OA替换项目中,喜提客户高度评价。近日,就企业数字化及斯歌产品、服务、体验等问题,斯歌与利星行汽车的管理信息系统总经理庄淑菱女士展开了一次对话访谈。 利星行汽车简介 利星行汽车于1993年进入中国大陆市场&#xf…

【实战经验】vant中picker选择器封装,让你的表单选择更简单

前言 对于选择器组件,vant 中的 picker 组件是一个非常合适的选择。它不仅提供了灵活的配置选项,还可以很方便地与其他 vant 组件结合使用,帮助我们快速搭建出漂亮、易用的移动端页面。在本文中,我将为大家介绍如何基于 vant 的 p…

【第二天议程】大会议题重磅出炉,豪华阵容等你面基!RustChinaConf 2023!

本次大会议题品质一流,嘉宾多来自行业一线,干货多多,且在各领域遍地开花,可看出Rust星星之火在中国已成燎原之势! 大会时间地址 6.17 - 6.18 浦东新区张杨路777号 上海锦江汤臣洲际酒店 官网地址 https://rustcc.cn/20…

# Windows 安装 Docker

Windows 安装 Docker 文章目录 Windows 安装 Docker何为Docker前言安装过程安装 Hyper-V安装 Docker Desktop for WindowsWSL 2 installation is incomplete 配置阿里云镜像加速地址Windows PowerShell查看Docker版本 Docker启动Nginx不挂载运行挂载运行随便启动一个 Nginx 容器…

【leetcode】189.轮转数组

方法1: 先把原数组拷贝一份,然后先将原数组的后k个拷贝,再将前numsSize-k个拷贝 void rotate(int* nums, int numsSize, int k) {//可能存在k>numsSize的情况,先处理kk k % numsSize;//拷贝数组int arr[numsSize];int i 0;in…

网络安全的学习路线是怎么样的?不同人路不同,快来对号入座吧!

最近看到网上有很多人在问诸如:“怎样成为网络安全工程师”等相关问题 这可能与近几年网络安全事件频发,国家对于互联网信息安全和互联网舆情的重视程度不断提升有关,网络信息安全工程师随之成为炙手可热的职业。关于职业前景的详细分析&…

【DBA 警世录之习惯性命令---读书笔记】

👈【上一篇】 💖The Begin💖点点关注,收藏不迷路💖 【下一篇】👉 🔻【💣 话题引入:既然 DBA 这个职业如此危险,那么哪些习惯是 DBA 必须养成的呢&#x…