范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

golang2021数据格式(91)指针使用入门与unsafe。Pointer

  我们已经知道,变量的本质对一块内存空间的命名,我们可以通过引用变量名来使用这块内存空间存储的值,而指针则是用来指向这些变量值所在内存地址的值。
  注:变量值所在内存地址的值不等于该内存地址存储的变量值。
  和 PHP、Python、Java 不同,Go 语言支持指针,如果一个变量是指针类型的,那么就可以用这个变量来存储指针类型的值。
  简单示例
  我们来看一个简单的示例:
  a := 100
  var ptr *int // 声明指针类型
  ptr = &a // 初始化指针类型值为变量 a
  fmt.Println(ptr)
  fmt.Println(*ptr)
  上面代码中的 ptr 就是一个指针类型,表示指向存储 int 类型值的指针。ptr 本身是一个内存地址值,所以需要通过内存地址进行赋值(通过 &a 可以获取变量 a 所在的内存地址),赋值之后,可以通过 *ptr 获取指针指向内存地址存储的变量值(我们通常将这种引用称作「间接引用」),所以上述代码打印结果是:
  0xc0000a2000
  100
  每次打印的 ptr 值可能不一样,因为存储变量 a 的内存地址在变动,不同操作系统打印的结果也不相同。   PHP/Java 中也有类似通过 & 进行引用传值的用法,其实这种用法的本质也是指针,只不过 PHP/Java 在语言级别屏蔽了指针的概念而已。   Go 语言之所以引入指针类型,主要基于两点考虑,一个是为程序员提供操作变量对应内存数据结构的能力;另一个是为了提高程序的性能(指针可以直接指向某个变量值的内存地址,可以极大节省内存空间,操作效率也更高),这在系统编程、操作系统或者网络应用中是不容忽视的因素。   使用场景   指针在 Go 语言中有两个典型的使用场景:   类型指针   切片   作为类型指针时,允许对这个指针类型数据指向的内存地址存储值进行修改,传递数据时如果使用指针则无须拷贝数据从而节省内存空间,此外和 C 语言中的指针不同,Go 语言中的类型指针不能进行偏移和运算,因此更为安全。   切片类型我们前面已经介绍过,由指向数组起始元素的指针、元素数量和容量组成,所以切片与数组不同,是引用类型,而非值类型。   基本使用   下面我们以一个简单的示例代码来演示 Go 语言中指针的基本使用。   指针类型的声明和初始化   指针变量在传值时之所以可以节省内存空间,是因为指针指向的内存地址的大小是固定的,在 32 位机器上占 4 个字节,在 64 位机器上占 8 个字节,这与指针指向内存地址存储的值类型无关。   关于指针类型的声明我们在开头已经演示过,这里我们再回头看下这段代码:   var ptr *int   fmt.Println(ptr)   a := 100   ptr = &a   fmt.Println(ptr)   fmt.Println(*ptr)   当指针被声明后,没有指向任何变量内存地址时,它的零值是 nil,然后我们可以通过在给定变量前加上取地址符 & 获取该变量对应的内存地址,再将其赋值给声明的指针类型,这样,就完成对指针类型的初始化了,接下来我们可以通过在指针类型前加上间接引用符 * 获取指针指向内存空间存储的变量值。   当然,和所有其他 Go 数据类型一样,我们也可以通过 := 对指针类型进行初始化:   a := 100   ptr := &a   fmt.Printf("%p ", ptr)   fmt.Printf("%d ", *ptr)   底层会自动判断指针的类型,在格式化输出时,可以通过 %p 来标识指针类型。   此外,还可以通过内置函数 new 声明指针:   ptr := new(int)   *ptr = 100   通过指针传值   我们再来看一个通过指针传值的示例,通过指针传值就类似于 PHP/Java 中通过引用传值,这样做的好处是节省内存空间,此外还可以在调用函数中实现对变量值的修改,因为直接修改的是指针指向内存地址上存储的变量值,而不是值拷贝。   为了体现出区别,我们先看不使用指针的值拷贝示例:   func swap(a, b int) {   a, b = b, a   fmt.Println(a, b)   }   func main() {   a := 1   b := 2   swap(a, b)   fmt.Println(a, b)   }   上述代码的打印结果是:   2 1   1 2   下面我们通过指针传值来重构上述代码:   func swap(a, b *int) {   *a, *b = *b, *a   fmt.Println(*a, *b)   }   func main() {   a := 1   b := 2   swap(&a, &b)   fmt.Println(a, b)   }   上述代码的打印结果是   2 1   2 1   因为这次,我们是通过指针传值的(&a、&b 都是指针,只不过我们没有显示声明而已),直接会对内存地址存储变量值进行交换操作,而主函数中的 a、b 变量仅仅是对应内存存储空间的别名而已,所以调用完 swap 函数后,它们所对应的内存空间存储值已经交换过来了。   unsafe.Pointer   我们前面介绍的指针都是被声明为指定类型的,而 unsafe.Pointer 是特别定义的一种指针类型,它可以包含任意类型变量的地址(类似 C 语言中的 void 类型指针)。Go 官方文档对这个类型有如下四个描述:   任何类型的指针都可以被转化为 unsafe.Pointer;   unsafe.Pointer      可以被转化为任何类型的指针;   uintptr 可以被转化为 unsafe.Pointer;   unsafe.Pointer 可以被转化为 uintptr。   指针类型转化   因此,unsafe.Pointer 可以在不同的指针类型之间做转化,从而可以表示任意可寻址的指针类型:   i := 10   var p *int = &i   var fp *float32 = (*float32)(unsafe.Pointer(p))   *fp = *fp * 10   fmt.Println(i) // 100   这里,我们将指向 int 类型的指针转化为了 unsafe.Pointer 类型,再转化为 *float32 类型(参考前面的 unsafe.Pointer 转化规则 1、2)并进行运算,最后发现 i 的值发生了改变。   这个示例说明了 unsafe.Pointer 是一个万能指针,可以在任何指针类型之间做转化,这就绕过了 Go 的类型安全机制,所以是不安全的操作。   指针运算实现   此外,根据上面的转化规则 3、4,unsafe.Pointer 还可以与 uintptr 类型之间相互转化,为什么要单独列出这个类型呢?   uintptr 是 Go 内置的可用于存储指针的整型,而整型是可以进行数学运算的!因此,将 unsafe.Pointer 转化为 uintptr 类型后,就可以让本不具备运算能力的指针具备了指针运算能力:   arr := [3]int{1, 2, 3}   ap := &arr   sp := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(ap)) + unsafe.Sizeof(arr[0])))   *sp += 3   fmt.Println(arr)   这里,我们将数组 arr 的内存地址赋值给指针 ap,然后通过 unsafe.Pointer 这个桥梁转化为 uintptr 类型,再加上数组元素偏移量(通过 unsafe.Sizeof 函数获取),就可以得到该数组第二个元素的内存地址,最后通过 unsafe.Pointer 将其转化为 int 类型指针赋值给 sp 指针,并进行修改,最终打印的结果是:   [1 5 3]   这样一来,就可以绕过 Go 指针的安全限制,实现对指针的动态偏移和计算了,这会导致即使发生数组越界了,也不会报错,而是返回下一个内存地址存储的值,这就破坏了内存安全限制,所以这也是不安全的操作,我们在实际编码时要尽量避免使用,必须使用的话也要非常谨慎。

数字人民币多个玩法齐亮相第四届数字中国建设成果展览会于4月25日至29日在福建省福州市举行,数家机构在其中的数字人民币专题展首次全面公开展示了其数字人民币的应用成果老年群体境外短期来华人士可通过智能机来领中汽协发布汽车数据可信存证区块链平台新华社北京4月28日电(记者高亢)记者获悉,中国汽车工业协会28日在北京组织召开智能网联汽车数据安全研讨会,研讨基于数据的安全监管与数据可信存证的相关问题,并发布了汽车数据可信存证天玑1200做游戏手机比骁龙870靠谱吗?今年1月19日,高通正式发布了骁龙870平台,作为旗舰骁龙888的补充第二天,也就是1月20日,联发科也正式发布了今年的旗舰SoC天玑1200平台。4个多月过去了,高通这边人丁兴旺如果中本聪一开始偷挖1千万个比特币储存,他现在会是世界首富吗据2013年的一篇文章分析指出,中本聪的持币数量为114。88万个。有证据显示比特币网络前36000个区块都是由同一台电脑挖出的,挖矿的人只可能是中本聪。当时每个区块的奖励是50个世界上第一个手机是怎么诞生的?谁是第一个用手机的人?世界上第一部手机是由RudyKrolopp设计,摩托罗拉生产的DynaTAC8000X。在1972年,Martincooper(手机之父)认命Krolopp为项目组长,让他带着团队iPadPro2021有必要买16GB运存的版本吗?要不要买,可以等等,等到今年WWDC之后,如果办公可以满足,可以买。刚预定了8G256版本iPadpro2021首发,527发货,也是很纠结,因为有的app还不支持MacM1跨平台富士康也失宠?智能工厂即将全面上线,以后怕是真的没工打了手机代工,相信很多小伙伴都不会陌生,尤其是苹果iPhone的代工厂富士康,也一度被誉为国内最好的手机生产线。当然,富士康也不仅仅只帮苹果做代工,它还帮助很多国产手机品牌进行组装代工华为和高通谁的5G技术更好一点?应邀回答本行业问题。其实就5G而言,也没有什么高通的5G,也没有什么华为的5G。现在我们说的5G,都是特指的3GPP的5GNR。5G是第五代移动通信制式,现在就全球范围来看,主要是华为布局6G技术,就连马斯克也没想到!这一次美还赶得上吗?不得不说实力证明一切,华为的5G技术领先于世界。当别人还在以安全为理由决定用不用华为的5G技术设备时,华为的6G布局再一次实现了弯道超车,成为了业界的领头羊。目前,我国已经建成5G万万想不到,卖6块的视频VIP,竟被罚了5000万腾讯视频2014年到2018年先后申请了腾讯视频V。QQ。COM腾讯视频VIP腾讯视频三个商标,作为一个付费观影平台,会员费是其重要收入来源。但国内不想付费的观众大有人在,于是隆耀苹果iOS15新功能曝光新UI应用分屏息屏显示近日,苹果正式确定了6月8日6月12日,举行WWDC2021全球开发者大会,届时可能会发布iOS15iPadOS15MacOS等全新系统。相比后两个系统,大家可能会更加关心iOS1
国家发改委等四部门加强对数据中心建设的统筹指导,坚决避免数据中心盲目无序发展据发改委网站12月8日消息,国家发展改革委等部门印发贯彻落实碳达峰碳中和目标要求推动数据中心和5G等新型基础设施绿色高质量发展实施方案。其中提出,在交通能源工业和市政等基础设施的规Django4。0正式发布,新的密码哈希器和Redis缓存后端Django4。0正式发布,4。0版本支持Python3。83。9和3。10。随着Django4。0的发布,Django3。2的主流支持已经结束。此版本主要有如下亮点新的Redis四部门到2025年数据中心和5G基本形成绿色集约的一体化运行格局中证网讯(记者刘丽靓)国家发改委12月8日消息,国家发改委中央网信办等四部门联合发布贯彻落实碳达峰碳中和目标要求推动数据中心和5G等新型基础设施绿色高质量发展实施方案提出,到202比普通相机小55万倍!只有盐粒大小你能接受吗?微型相机以往在医疗时都较为常用,但尺寸及影像质素都受到一定限制。不过最近美国普林斯顿大学及华盛顿大学的研究人员,就共同开发出一种只有盐粒体积的相机,比传统大家常用的相机要小5500华为P60Pro规格被曝无孔全面屏伸缩1英寸主摄,有望回归5G没想到吧,华为Mate50还未发布,作为排在其后头发布的新机华为P60就传来了消息,让不少花粉又惊又喜。据爆料称,华为P60系列有望在2022年第三季度完成发布,据介绍,华为P60裁员浪潮下,如何生存?裁员浪潮来袭最近优化人员结构这个词,热度很高,相关的各种报道也挺多的,很多人也都关心这个事情。被曝出来的,大多是大公司的,比如阿里向社会传输近2万人,随后爱奇艺被爆出优化人员结构,请教,荣耀V30pro和荣耀30哪个好一点?这几年华为手机越来越得到国人认可,但是华为手机产品型号繁多,很多人想入手一款适合自己的手机也是挑花了眼。今天借着答题机会,将荣耀30和荣耀V30Pro综合对比分析,到底那款手机更值锂电池大跌,白酒又成香饽饽?大家好,距上次发文又过了差不多10天了,在11月29的时候我又再次给持仓新能源车锂电池的提示了高位风险,可无奈还有人在上面等被割,为什么新能源车锂电池能撑到现在,我在29号的文章说关于我国的芯片国货之光在以前,我们的芯片还是十分糟糕的时候,我们常常被外国人欺负,比如说内存工厂又火灾了。我们面对着涨价的内存条,开心不起来。不过后来我们也有了自己的内存条。比如光威,就再也不用再次确认!华为芯片解决方案正在路上,5G回归指日可待说到华为,相信大部分的人都会为其竖起大拇指。在经历了多轮的制裁之后,华为依旧没有倒下,反而展现出自己在困难面前,不屈不挠自力更生的精神。就在前几天,一条采访华为消费者业务中东欧北欧华为自研PC芯片曝光,预计明年6月发布国产自研芯片最近捷报频传,涉及领域包括8K超高清图像传感芯片4K级显卡GPU芯片以及智能手表等等。近日又有消息称华为代号为盘古的自研处理器芯片曝光,将会用于PC电脑设备,目标直指取