首页 > 其他分享 >Go语言内置集合的隐式指针

Go语言内置集合的隐式指针

时间:2024-10-31 10:48:44浏览次数:7  
标签:map 内置 传递 集合 Go 隐式 指针

在 Go 语言中,有几种内置集合类型(如 slicemapchannel),这些类型的特殊之处在于它们实际上是隐式指针
这意味着当我们将这些集合类型传递给函数或方法时,传递的是它们的引用,而不是拷贝。
这种特性使得这些集合能够在函数中直接修改原始数据,而不需要显式传递指针。

1. 内置集合的隐式指针特性

在 Go 中,slicemapchannel 都是引用类型。当将它们作为参数传递给函数时,会保持对原始集合的引用。
任何对这些集合的修改都会影响到原始数据,而不需要使用 & 符号来获取它们的地址。

示例:slice 的隐式指针特性

package main

import "fmt"

func modifySlice(s []int) {
    s[0] = 42 // 修改切片的第一个元素
}

func main() {
    numbers := []int{1, 2, 3}
    modifySlice(numbers)
    fmt.Println(numbers) // 输出: [42, 2, 3]
}

在上面的例子中,numbers 切片被传递给 modifySlice 函数。虽然 modifySlice 函数的参数类型是 []int,但它并不是一个拷贝,而是一个对原始切片的引用。因此,在 modifySlice 中对 s[0] 的修改会反映到原始的 numbers 切片上。

2. 为什么 Go 选择让这些集合成为隐式指针?

Go 语言设计成这样,主要是为了性能和内存管理的方便。复制大规模的数据结构(如数组、映射)会占用大量内存,并可能导致性能下降。
通过让这些集合类型作为引用传递,Go 避免了不必要的拷贝,从而提高了效率。

3. 各内置集合的隐式指针特性

  • slice:切片是一个对底层数组的引用,它包含一个指向底层数组的指针、长度和容量。传递切片会复制这个切片结构体(包含指针、长度、容量),但它仍然指向原始数组,因此可以直接修改数据。

  • map:映射在底层实现是一个指针结构,传递 map 就是传递这个指针。因此,对 map 的任何修改操作(如增删键值对)会直接反映在原始 map 上。

  • channel:通道在底层也是一个指向具体数据结构的引用。传递 channel 时传递的是这个引用,因此多个 Goroutine 可以安全地通过同一个通道来通信,而不需要复制通道。

4. 对比值类型和引用类型

Go 语言中的值类型包括 intfloatboolstring 以及 array 等。值类型在赋值或传递时会进行拷贝,而不会影响原始数据。因此,对于值类型,如果希望修改原始数据,需要显式传递指针。

值类型 vs 引用类型

package main

import "fmt"

func modifyValue(x int) {
    x = 42
}

func modifyPointer(x *int) {
    *x = 42
}

func main() {
    a := 10
    modifyValue(a)
    fmt.Println(a) // 输出: 10,未修改

    modifyPointer(&a)
    fmt.Println(a) // 输出: 42,修改了原始值
}

在这个例子中:

  • modifyValue 函数传递的是值的副本,因此对 x 的修改不会影响原始变量 a
  • modifyPointer 使用指针传递,因此对指针的修改会影响到原始变量 a

5. 使用隐式指针集合时的注意事项

尽管隐式指针的特性很方便,但在使用时需要注意:

  • 并发访问问题mapslice 不是线程安全的,在并发情况下可能会引发数据竞争。为避免数据竞态,需使用 sync.Mutexsync.RWMutex 来同步访问。

  • 避免误操作:隐式指针集合类型可以在函数中修改原始数据,因此在编写代码时需注意,这种修改可能会导致意外结果。如果不希望在函数内修改原始数据,可以考虑显式地创建副本。

6. 总结

Go 语言中的 slicemapchannel 作为引用类型,通过隐式指针的特性让它们在传递时始终保持对原始数据的引用。
这样设计有助于提高性能,并简化代码,使得开发者无需显式使用指针即可修改集合内容。这种隐式指针特性是 Go 语言提高性能、减少内存复制的重要手段。

标签:map,内置,传递,集合,Go,隐式,指针
From: https://www.cnblogs.com/niumachen/p/18517260

相关文章

  • golang编写代码发邮件
    AI提示词用go语言直接向mx记录的25端口发邮件,要采用STARTTLS连接方式,要包含Message-IDpackagemainimport("crypto/tls""fmt""log""math/rand""net""net/mail""net/smtp""st......
  • gomail 发邮件
    gomail发邮件packagemainimport( "crypto/tls" "fmt" "log" "strconv" "gopkg.in/gomail.v2")funcSendMail(mailTo[]string,subjectstring,bodystring)error{ //设置邮箱主体 mailConn:=map[string]str......
  • Django学习-缓存
    定义:当遇到这种查询慢的时候 ,我们就可以在查询完数据库的时候,将查询的结果存储到缓存中一份,下次查询的时候直接从缓存中获取,避免查询数据库耗费时间,当然需要设置一个过期时间,来更新缓存Django中设置缓存-数据库缓存 配置:  Django中设置缓存-本地内存缓存(测试可以使......
  • Typora+gitee+picgo突然失效,此前Typora里面的图片image load failed,图片是gitee链接
    Typora+gitee+picgo突然失效,此前Typora里面的图片imageloadfailed,图片是gitee链接单纯把http链接复制粘贴到网页可以打开图片,但在Typora里面就是加载失败尝试解决方法如下:1、怀疑是Typora版本问题从用了几年的TyporaV1.02版本更新到最新的V1.9版本,发现所有图片又全都......
  • Vue.js内置指令全解析:从基础到实践
    文章目录前言Vue.js内置指令详解v-textv-htmlv-showv-ifv-elsev-else-ifv-forv-onv-bindv-modulev-slotv-prev-oncev-memov-cloak结尾前言在Vue.js的世界里,指令是连接数据和视图的桥梁,它们为开发者提供了一种声明式的方法来处理常见的任务。本文将详细介绍Vue.js......
  • 数学建模,非线性规划lingo例题
    题目:家具制造厂板材优化问题(具体化)背景:一家家具制造厂生产两种类型的家具:办公桌和办公椅。工厂有两种不同规格的板材可供使用,每种板材的成本和利用率不同。工厂的目标是在有限的板材资源和生产时间内,最大化利润,同时考虑板材的余料损失。决策变量:x1x1​:生产的办公桌数量x2x2......
  • Leangoo敏捷管理工具支持私有部署
    ​在当今快速变化的商业环境中,敏捷开发已成为许多企业追求高效和灵活性的首选方法。作为一款专注于敏捷管理的工具,Leangoo以其强大的功能和灵活性而备受欢迎。其中一个显著的优势就是它支持私有部署,为企业提供了更多的安全性和可控性。1.私有部署的优势**数据安全** 在企业......
  • 在openwrt上跑golang程序
    1.安装Go语言、搭建开发环境https://blog.csdn.net/qq_38105536/article/details/1426351322.VMwareWorkstation部署最新版OpenWrt23.05.3https://blog.csdn.net/gtj0617/article/details/137706312桥接模式(负责物理网络连接状态),设置ip:192.168.0.11设置root密码root@Ope......
  • Javaweb 实验6 JSP内置对象
    我发现了有些人喜欢静静看博客不聊天呐,但是ta会点赞。这样的人呢帅气低调有内涵,美丽大方很优雅。说的就是你,不用再怀疑哦目的:掌握JSP内置对象的使用。理解JSP的作用域掌握JSP的表达式使用实验要求:完成实验题目要求提交实验报告,将代码和实验结果页面截图放入报告中第......
  • 【GiraKoo】C++编译中常用的内置宏
    开源项目:https://girakoo.com/联系方式:[email protected]简介针对不同的平台,很多头文件,函数名称,类型占用空间不一致。为了保证跨平台可编译,经常需要在项目中使用宏进行区分系统宏操作系统可使用的宏Windows32位_WIN32Windows64位_WIN32;_WIN64Linux__linu......