Go语言地址引用的问题解决

 更新时间:2025年11月21日 09:25:57   作者:好易学·数据结构  
本文主要介绍了Go语言中channel和slice的引用行为,它们在操作时会共享同一块数据,及在追加数据时可能开辟新内存的情况,下面就来详细的介绍一下,感兴趣的可以了解一下

1、channel

先看以下代码:

package main

import "fmt"

func main() {
	ch1 := make(chan int, 3)
	ch2 := ch1
	ch1 <- 123
	ch2 <- 456
	fmt.Println(ch1, ch2)     //输出地址是否一样?  TODO:打印结果是?
	fmt.Println(<-ch2, <-ch1) // ch2中的数据是:456; ch1中的数据是123;TODO:打印结果是?
}

输出结果:

代码分析:

在以上代码中,新定义的变量ch2:=ch1 ;ch2是地址引用,ch1,ch2地址指向的是同一块数据,ch1、ch2都可以改变数据。

2、slice

看看以下代码:

package main

import "fmt"

func main() {
	s := make([]int, 3)
	s1 := s
	s2 := s
	s[0] = 123
	s1[1] = 456
	s2[2] = 789
	fmt.Println("原始切片:", s)
	fmt.Println("赋值切片:", s1)
	fmt.Println("赋值切片:", s2)
	fmt.Println("切片的长度、容量为:", len(s), cap(s))
	fmt.Printf("追加之前的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
	fmt.Println("====执行append操作====")
	s2 = append(s2, 123)
	fmt.Printf("追加之后的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
	fmt.Println("原始切片s:", s)
	fmt.Println("赋值切片s1:", s1)
	fmt.Println("赋值切片s2:", s2)
}

输出结果:

代码分析:起初,s,s1,s2都指向同一块数据。所以任意一个变量修改了该块数据,其他变量查到的都是修改之后的数据。

指向:

s2 = append(s2, 123),会在末尾追加一个元素,由于现有s2的
cap(s)=3, len(s)=3;

在追加数据时,容量已经不够,会开辟新的内存,将现有数据s2拷贝,形成新的s2。当然在容量足够的情况下,不会开辟新的内存空间。

再来看以下代码:(容量大于append的数据数量)

package main

import "fmt"

func main() {
	s := make([]int, 3,6)
	s1 := s
	s2 := s
	s[0] = 123
	s1[1] = 456
	s2[2] = 789
	fmt.Println("原始切片:", s)
	fmt.Println("赋值切片:", s1)
	fmt.Println("赋值切片:", s2)
	fmt.Println("切片的长度、容量为:", len(s), cap(s))
	fmt.Printf("追加之前的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
	fmt.Println("====执行append操作====")
	s2 = append(s2, 123)
	fmt.Printf("追加之后的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
	s[0]=888 // TODO:会修改s1、s2吗
	fmt.Println("原始切片s:", s)
	fmt.Println("赋值切片s1:", s1)
	fmt.Println("赋值切片s2:", s2)
}

输出效果:

在以上代码中添加内容:

package main

import "fmt"

func main() {
	s := make([]int, 3,6)
	s1 := s
	s2 := s
	s[0] = 123
	s1[1] = 456
	s2[2] = 789
	fmt.Println("原始切片:", s)
	fmt.Println("赋值切片:", s1)
	fmt.Println("赋值切片:", s2)
	fmt.Println("切片的长度、容量为:", len(s), cap(s))
	fmt.Printf("追加之前的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
	fmt.Println("====执行append操作====")
	s2 = append(s2, 123)
	fmt.Printf("追加之后的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
	s[0]=888 // TODO:会修改s1、s2吗
	fmt.Println("原始切片s:", s)
	fmt.Println("赋值切片s1:", s1)
	fmt.Println("赋值切片s2:", s2)
	fmt.Println("执行以下操作,输出结果又是什么呢?")
	s = append(s, 666)
	fmt.Println("原始切片s:", s)
	fmt.Println("赋值切片s1:", s1)
	fmt.Println("赋值切片s2:", s2)
}

特别说明:Go语言为了节省内存空间,对于切片、map、channel、指针等地址引用的变量,会操作同一块地址对应的数据,在操作时也特别留意。

到此这篇关于Go语言地址引用的问题解决的文章就介绍到这了,更多相关Go语言地址引用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言操作Excel的实现示例

    Go语言操作Excel的实现示例

    excelize是一个功能丰富且易于使用的Go语言库,它极大地简化了Excel文件的读写操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-12-12
  • go中Excelize处理excel表实现带数据校验的文件导出

    go中Excelize处理excel表实现带数据校验的文件导出

    本文主要介绍了go中Excelize处理excel表实现带数据校验的文件导出,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • golang如何通过viper读取config.yaml文件

    golang如何通过viper读取config.yaml文件

    这篇文章主要介绍了golang通过viper读取config.yaml文件,围绕golang读取config.yaml文件的相关资料展开详细内容,需要的小伙伴可以参考一下
    2022-03-03
  • jenkins配置golang 代码工程自动发布的实现方法

    jenkins配置golang 代码工程自动发布的实现方法

    这篇文章主要介绍了jenkins配置golang 代码工程自动发布,jks是个很好的工具,使用方法也很多,我只用了它简单的功能,对jenkins配置golang相关知识感兴趣的朋友一起看看吧
    2022-07-07
  • go语言K8S 的 informer机制浅析

    go语言K8S 的 informer机制浅析

    这篇文章为大家主要介绍了go语言K8S 的 informer机制浅析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Golang信号处理及如何实现进程的优雅退出详解

    Golang信号处理及如何实现进程的优雅退出详解

    这篇文章主要给大家介绍了关于Golang信号处理及如何实现进程的优雅退出的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-03-03
  • Golang切片连接成字符串的实现示例

    Golang切片连接成字符串的实现示例

    本文主要介绍了Golang切片连接成字符串的实现示例,可以使用Go语言中的内置函数"String()"可以将字节切片转换为字符串,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • Go检查结构体中是否存在某个字段及创建结构体切片或映射

    Go检查结构体中是否存在某个字段及创建结构体切片或映射

    这篇文章主要为大家介绍了Go检查结构体中是否存在某个字段及创建结构体切片或映射实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • go xorm存库处理null值问题

    go xorm存库处理null值问题

    这篇文章主要介绍了go xorm存库处理null值问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Golang加权轮询负载均衡的实现

    Golang加权轮询负载均衡的实现

    负载均衡器在向后端服务分发流量负载时可以使用几种策略。本文主要介绍了Golang加权轮询负载均衡,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06

最新评论