当前位置: 首页 > news >正文

Go 指针

指针

在编程中,一个内存地址用来定位一段内存。

通常地,一个内存地址用一个操作系统原生字(native word)来存储。 一个原生字在32位操作系统上占4个字节,在64位操作系统上占8个字节。 所以,32位操作系统上的理论最大支持内存容量为4GB(1GB == 230字节),64位操作系统上的理论最大支持内存容量为264Byte,即16EB(EB:艾字节,1EB == 1024PB, 1PB == 1024TB, 1TB == 1024GB)。

内存地址的字面形式常用整数的十六进制字面量来表示,比如0x1234CDEF。

在Go中,一个无名指针类型的字面形式为*T,其中T为一个任意类型。类型T称为指针类型*T的基类型(base type)。 如果一个指针类型的基类型为T,则我们可以称此指针类型为一个T指针类型。

虽然我们可以声明具名指针类型,但是一般不推荐这么做,因为无名指针类型的可读性更高。

如果一个指针类型的底层类型是*T,则它的基类型为T。

如果两个无名指针类型的基类型为同一类型,则这两个无名指针类型亦为同一类型。

*int  // 一个基类型为int的无名指针类型。
**int // 一个多级无名指针类型,它的基类型为*int。type Ptr *int // Ptr是一个具名指针类型,它的基类型为int。
type PP *Ptr  // PP是一个具名多级指针类型,它的基类型为Ptr。

如何获取一个指针值?

有两种方式来得到一个指针值:

  1. 我们可以用内置函数new来为任何类型的值开辟一块内存并将此内存块的起始地址做为此值的地址返回。 假设T是任一类型,则函数调用new(T)返回一个类型为*T的指针值。 存储在返回指针值所表示的地址处的值(可被看作是一个匿名变量)为T的零值。

  1. 我们也可以使用前置取地址操作符&来获取一个可寻址的值的地址。 对于一个类型为T的可寻址的值t,我们可以用&t来取得它的地址。&t的类型为*T。

一般说来,一个可寻址的值是指被放置在内存中某固定位置处的一个值(但放置在某固定位置处的一个值并非一定是可寻址的)。 目前,我们只需知道所有变量都是可以寻址的;但是所有常量、函数返回值和强制转换结果都是不可寻址的。 当一个变量被声明的时候,Go运行时将为此变量开辟一段内存。此内存的起始地址即为此变量的地址。

对于基类型为T的指针类型的一个指针值p,我们可以用*p来表示地址p处的值。 此值的类型为T。*p称为指针p的解引用。解引用是取地址的逆过程。

解引用一个nil指针将产生一个panic。

package mainimport "fmt"func main() {p0 := new(int)   // p0指向一个int类型的零值fmt.Println(p0)  // (打印出一个十六进制形式的地址)fmt.Println(*p0) // 0x := *p0              // x是p0所引用的值的一个复制。p1, p2 := &x, &x      // p1和p2中都存储着x的地址。// x、*p1和*p2表示着同一个int值。fmt.Println(p1 == p2) // truefmt.Println(p0 == p1) // falsep3 := &*p0            // <=> p3 := &(*p0)// <=> p3 := p0// p3和p0中存储的地址是一样的。fmt.Println(p0 == p3) // true*p0, *p1 = 123, 789fmt.Println(*p2, x, *p3) // 789 789 123fmt.Printf("%T, %T \n", *p0, x) // int, intfmt.Printf("%T, %T \n", p0, p1) // *int, *int
}

在Go中,所有的赋值(包括函数调用传参)过程都是一个值复制过程。 所以在上面的double函数体内修改的是变量a的一个副本,而没有修改变量a本身。

当然我们可以让double函数返回输入参数的两倍数,但是此方法并非适用于所有场合。

package mainimport "fmt"func double(x *int) {*x += *xx = nil // 此行仅为讲解目的
}func main() {var a = 3double(&a)fmt.Println(a) // 6p := &adouble(p)fmt.Println(a, p == nil) // 12 false
}

通过将double函数的输入参数的类型改为*int,传入的实参&a和它在此函数体内的一个副本x都引用着变量a。 所以对*x的修改等价于对*p(也就是变量a)的修改。 换句话说,新版本的double函数内的操作可以反映到此函数外了。

当然,在此函数体内对传入的指针实参的修改x = nil依旧不能反映到函数外,因为此修改发生在此指针的一个副本上。 所以在double函数调用之后,局部变量p的值并没有被修改为nil。

在Go中返回一个局部变量的地址是安全的

Go是支持垃圾回收的,所以一个函数返回其内声明的局部变量的地址是绝对安全的。

func newInt() *int {a := 3return &a
}

Go指针的一些限制

施加限制,Go指针保留了C指针的好处,同时也避免了C指针的危险性。

  • 在Go中,指针是不能参与算术运算的。比如,对于一个指针p, 运算p++和p-2都是非法的。

  • 如果p为一个指向一个数值类型值的指针,*p++将被编译器认为是合法的并且等价于(*p)++。 换句话说,解引用操作符*的优先级都高于自增++和自减--操作符。

  • 一个指针值不能和其它任一指针类型的值进行比较

Go指针值是支持(使用比较运算符==和!=)比较的。 但是,两个指针只有在下列任一条件被满足的时候才可以比较:
这两个指针的类型相同。
其中一个指针可以被隐式转换为另一个指针的类型。换句话说,这两个指针的类型的底层类型必须一致并且至少其中一个指针类型为无名的(考虑结构体字段的标签)。
其中一个并且只有一个指针用类型不确定的nil标识符表示。
  • 一个指针类型的值不能被随意转换为另一个指针类型

在Go中,只有如下某个条件被满足的情况下,一个类型为T1的指针值才能被显式转换为另一个指针类型T2:
类型T1和T2的底层类型必须一致(忽略结构体字段的标签)。 特别地,如果类型T1和T2中只要有一个是无名类型并且它们的底层类型一致(考虑结构体字段的标签),则此转换可以是隐式的。
类型T1和T2都为无名类型并且它们的基类型的底层类型一致(忽略结构体字段的标签)。

Go指针的限制是可以被打破的

unsafe标准库包中提供的非类型安全指针(unsafe.Pointer)机制可以被用来打破上述Go指针的安全限制。 unsafe.Pointer类型类似于C语言中的void*。 但是,通常地,非类型安全指针机制不推荐在Go日常编程中使用。

相关文章:

Go 指针

指针在编程中&#xff0c;一个内存地址用来定位一段内存。通常地&#xff0c;一个内存地址用一个操作系统原生字&#xff08;native word&#xff09;来存储。 一个原生字在32位操作系统上占4个字节&#xff0c;在64位操作系统上占8个字节。 所以&#xff0c;32位操作系统上的理…...

shardingsphere5.1.1分表分库yaml配置 自定义策略

前言通过阅读官方稳定给出示例 https://shardingsphere.apache.org/document一、基本配置示例spring:sharding:datasource:names: ds0, ds1ds0:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/db0username: rootpassword: rootds1:driver-class-na…...

“探索未来:VR全景直播技术引领新媒体时代”

随着虚拟现实技术的不断发展&#xff0c;VR全景直播已经成为了越来越受欢迎的直播形式。VR全景直播可以让观众通过虚拟现实设备亲临直播现场&#xff0c;享受身临其境的观看体验。VR全景直播是什么&#xff1f; VR全景直播是虚拟现实技术和直播的结合。相对于传统直播&#xff…...

Spring Cloud(微服务)学习篇(六)

Spring Cloud(微服务)学习篇(六) 2 Sentinel实现流量规则(控制台版) 2.1 变更pom.xml(shop-user-server项目)代码 2.1.1 加入如下依赖 <!--熔断限流--> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-…...

MATLAB-Scatter3-三维散点图投影至XYZ三个平面

MATLAB-Scatter3函数可以绘制立体的三维散点图&#xff0c;但有时候需要在该立体图中分析X-Y-Z三者的关系&#xff0c;即1副图呈现出4个信息&#xff0c;XYZ综合信息、XY信息、XZ信息、YZ信息。现有的Scatter3无法实现该功能&#xff0c;本文可实现Scatter3三维立体散点图在三个…...

Unity/C#------委托与事件(一篇文章彻底搞懂...)

一&#xff1a;委托 所有的代码语言创造者母语都是英语&#xff0c;我们从英语翻译到中文的过程中难免会存在一些不太能还原本意的词&#xff0c;比如我之前一直不理解构造函数和析构函数&#xff0c;只知道这俩货作用相反&#xff0c;直到我看到了它的英文意思&#xff0c;Con…...

别再为 Jenkins 安装烦恼,Docker 帮你轻松解决

前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓月&#xff0c;本文收录与云原生相关的专栏&#xff0c;以下是我的简介&#xff1a; &#x1f3e0;个人主页&#xff1a;我是沐风晓月 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是沐风晓月&#xff0c;双…...

汇编语言程序设计(一)

前言 在学习汇编语言之前&#xff0c;我们应该要知道汇编语言他是一门怎么样的语言。汇编语言是直接工作在硬件上的一门编程语言&#xff0c;学习汇编语言之前最好先了解一下计算机硬件系统的结构和工作原理。学习汇编语言的重点是学习如何利用硬件系统的编程结构和指令集进而…...

【uni-app教程】四、UniAPP 路由配置及页面跳转

四、UniAPP 路由配置及页面跳转 (1) 路由配置 uni-app页面路由为框架统一管理&#xff0c;开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在 app.json 中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同&#xff0c;如仍希望采用 Vue …...

ROS从入门到精通系列(二十八)-- ROS控制器图形化界面开发

ROS (Robot Operating System, 机器人操作系统) 作为机器人软件中的通信及控制中间件,提供一系列程序库和工具以帮助软件开发者创建机器人应用软件。它提供了硬件抽象、设备驱动、函数库、可视化工具、消息传递和软件包管理等诸多功能。ROS遵循BSD开源许可协议。 随着机器人智…...

Submodule命令:android如何将自己项目中的某个Module作为gitlab中第三方公共库

一、创建远程公共库 1、Android Studio创建本地仓库 创建一个新的module 在新建module中添加代码(此处示例代码) 右击新建的module&#xff0c;打开新建module的命令行界面&#xff0c; 因为我们只上传这个module的代码&#xff0c;而不是整个项目的代码 命令行中输入以下命令…...

MySQL索引事务

1.索引1.1概念索引是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引&#xff0c;并指定索引的类型&#xff0c;各类索引有各自的数据结果实现。&#xff08;这里只用通俗的语言和图片进行介绍&#xff09;1.2作用数据库中的表…...

ISO27001信息安全管理体系认证

​ISO信息安全管理体系认证 一、什么是ISO信息安全管理体系认证&#xff1f; ISO是信息安全管理体系认证&#xff0c;是由国际标准化组织&#xff08;ISO&#xff09;采纳英国标准协会BS-2标准后实施的管理体系&#xff0c;成为了“信息安全管理”的国际通用语言&#xff0c;企…...

Linux应用GUI开发C++ 之gtkmm4(1)

目录概述GTKgtkmm安装gtkmm4hello,worldcodelite配置代码解释概述 GTK GTK是一个小部件工具包。GTK创建的每个用户界面都由小部件组成。这是在C语言中使用GObject实现的&#xff0c;GObject是一个面向对象的C语言框架。窗口小部件是主容器。然后通过向窗口中添加按钮、下拉菜…...

选课系统的设计与实现

技术&#xff1a;Java等摘要&#xff1a;目前国内各高校的规模越来越大&#xff0c;进而造成教师教学管理等工作量日趋加大。然而&#xff0c;现代教育的信息化、网络化已经成为教育发展的一个重要方向&#xff0c;同时也为解决高校教学管理效率低下的现状&#xff0c;使管理突…...

关于安卓的一些残缺笔记

安卓笔记Android应用项目的开发过程Android的调试Android项目文档结构Intent的显式/隐式调用Activity的生命周期1个Activity界面涉及到生命周期的情况2个Activity界面涉及到生命周期的情况Android布局的理论讲解Activity界面布局ContentProvider是如何实现数据共享Android整体架…...

MySQL 中的锁有哪些类型,MySQL 中加锁的原则

锁的类型MySQL 找那个根据加锁的范围&#xff0c;大致可以分成全局锁&#xff0c;表级锁和行级锁。全局锁全局锁&#xff0c;就是对整个数据库加锁。加锁flush tables with read lock解锁unlock tables全局锁会让整个库处于只读状态&#xff0c;之后所有的更新操作都会被阻塞&a…...

Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作

场景 Sqlite数据库 SQLite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。 它是一个零配置的数据库&#xff0c;这意味着与其他数据库不一样&#xff0c;您不需要在系统中配置。 就像其他数据库&#xff0c;SQLite 引擎不…...

2023最新版本RabbitMQ下载安装教程

一、RabbitMQ简介 RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。主要用于在进程、应用程序和服务器之间交换数据&#xff0c;可以通过插件支持进行扩展&#xff0c;支持许多协议&#xff0c;并提供高性能、可靠性、集群和高可用队列。 AMQP &#xff1a;Advanced Me…...

如何使用码匠连接 Elasticsearch

目录 在码匠中集成 Elasticsearch 在码匠中使用 Elasticsearch 关于码匠 Elasticsearch 是一个开源的分布式搜索和分析引擎&#xff0c;常用于处理大规模数据集的搜索、实时数据分析和数据挖掘任务。它支持多种数据源&#xff0c;包括关系型数据库&#xff08;如 MySQL、Pos…...

jmeter学习笔记二(jmeter函数与后置处理器)

Jmeter重要的函数 ${__counter(,)} 计数器 ​ ${__counter(TRUE,)} 默认加1; TRUE&#xff0c;每个用户有自己的计数器&#xff1b;FALSE&#xff0c;使用全局计数器 ​ 计数器元件&#xff0c;可以设置起始值&#xff0c;间隔值&#xff0c;最大值。运行结果超过最大值时&a…...

【独家】华为OD机试提供C语言题解 - 子序列长度

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明子序…...

Java之注解

注解1.1 注解的概念1.2 内置注解1.3 元注解1.4 自定义注解1.1 注解的概念 Annotation 是从JDK5.0 开始引入的新技术 Annotation的作用&#xff1a; 不是程序本身&#xff0c;可以对程序做出解释&#xff08;这一点和注释comment没什么区别&#xff09;可以被其他程序&#xff…...

【C++】string

【C修炼秘籍】string 目录 【C修炼秘籍】string 文章目录 前言 一、标准库里的string 二、string常用接口功能简介&#xff08;具体使用和底层转到模拟实现&#xff09; 1、string类的常见构造函数 2、string类对象的容量操作 3、string类对象的访问及遍历操作 4、 string类对象…...

JVM详解——执行引擎

如果有兴趣了解更多相关内容&#xff0c;欢迎来我的个人网站看看&#xff1a;耶瞳空间 一&#xff1a;执行引擎介绍 “虚拟机”是一个相对于“物理机”的概念&#xff0c;这两种机器都有代码执行能力&#xff0c;其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和…...

python学习——【第二弹】

前言 上一篇文章 python学习——【第一弹】给大家介绍了python中的基本数据类型等&#xff0c;这篇文章接着学习python中的运算符的相关内容。 运算符 python中的运算符主要有&#xff1a;算术运算符&#xff0c;赋值运算符&#xff0c;比较运算符&#xff0c;布尔运算符以及…...

242. 有效的字母异位词 349. 两个数组的交集

给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a; 若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 示例 1: 输入: s “anagram”, t “nagaram” 输出: true 示例 2: 输入: s “rat…...

web网页设计——JavaScript一些语法

1、事件监听 语法&#xff1a; <1> 元素对象.addEventListener(‘事件类型’,要执行的函数&#xff09; 三要素&#xff1a;&#xff08;1&#xff09;、事件源 &#xff08;2&#xff09;事件类型 &#xff08;3&#xff09;执行的函数 <2>元素对象.on事件类型 …...

php宝塔搭建部署实战CSM会议室预约系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套基于fastadmin开发的CSM会议室预约系统的源码。感兴趣的朋友可以自行下载学习。 技术架构 PHP7.2 nginx mysql5.7 JS CSS HTMLcnetos7以上 宝塔面板 文字搭建教程 下载源码&#xff0…...

嵌入式知识点-SPI通讯

该文原自 &#xff1a; 正点原子 01 SPI概述 SPI (Serial Peripheralinterface),顾名思义就是串行外围设备接口。SPI是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的管脚上只占用四根线&#xff0c;节约了芯片的管脚&#xff0c;同…...

晋城网站制作/seo推广需要多少钱

E5□C(E5AC/E5EC/E5CC/E5DC)温控器如何进行AT自整定&#xff1f;第一步&#xff1a;更改控制方式为PID首先在操作菜单下按上键或下键设定目标值&#xff0c;然后按菜单键3秒以上进入初始设定菜单&#xff0c;按模式键找到CNTL选项并设为PID&#xff0c;即控制方式为PID方式&…...

接单干活的平台/朝阳区seo搜索引擎优化怎么样

Python入门之第三方模块安装 平台&#xff1a;Win10 x64 Anaconda3-5.3.0 &#xff08;Python3.7.0&#xff09; Issue说明&#xff1a;pip install line_profiler-2.1.2-cp37-cp37m-win_amd64.whl报错pip版本过低&#xff0c;需要更新1.19.0&#xff0c;而当前的版本是0.9.0 …...

那个网站做服装批发/长沙seo优化

栏目今天翻译介绍列表推导式使用的注意事项。Python 列表推导式使用注意事项Python 列表推导式并不是给初学者用的&#xff0c;因为它非常反直觉&#xff0c;甚至对于有其他编程语言背景的人也是如此。我们接触到 List 的使用时&#xff0c;学习的内容都是零散的。所以我们缺少…...

温州市建设小学大南网站/南宁关键词排名公司

5 类型参数列表我们学习了模板函数和模板类的定义和使用。但是&#xff0c;看到的“类型形参表”都只有一个元素&#xff0c;那么&#xff0c;如果要定义多个类型&#xff0c;应该怎么样操作&#xff1f;在telplate<类型形参表>中&#xff0c;“类型形参表”可以定义多个…...

天津做网站好的公司/互联网广告代理商

参考链接 点击跳转 转载于:https://www.cnblogs.com/daydayhave/p/9602583.html...

自己免费怎么制作网站吗/海城seo网站排名优化推广

最近项目任务有需求&#xff0c;想探究一下对未知未加密网络协议的解析。 之前只了解过基本的计算机网络知识&#xff0c;对于具体的网络协议&#xff0c;更多是学术上的认识&#xff0c;而没有工程上的认知与实践。因此对于网络协议解析的工作&#xff0c;可谓是一筹莫展。 各…...