Golang 拷贝Array或Slice的操作
作者:neweastsun 时间:2024-04-30 10:02:40
Golang中Array是值类型而slice是引用类型。因此两者之间的赋值或拷贝有些差异,本文带你了解各自的差异。
1. 拷贝array
前面提及数组是值类型,所以数组变量名不是指向第一个元素的指针。事实上它表示整个数组,下面两者情况将自动创建数组:
数组变量赋值给另一个数组变量
数组变量传递作为函数参数
请看示例:
package main
import "fmt"
func main() {
sample1 := [2]string{"a", "b"}
fmt.Printf("Sample1 Before: %v\n", sample1)
sample2 := sample1
sample2[0] = "c"
fmt.Printf("Sample1 After assignment: %v\n", sample1)
fmt.Printf("Sample2: %v\n", sample2)
test(sample1)
fmt.Printf("Sample1 After Test Function Call: %v\n", sample1)
}
func test(sample [2]string) {
sample[0] = "d"
fmt.Printf("Sample in Test function: %v\n", sample)
}
输出结果:
Sample1 Before: [a b]
Sample1 After assignment: [a b]
Sample2:
Sample in Test function: [d b]
Sample1 After Test Function Call: [a b]
我们稍作解释:
sample1 赋给 sample2 ,然后修改sample2中第一个元素。打印sample1验证是否有影响,当然没有改变。这是因为sample1 赋给 sample2,会创建sample1的拷贝给sample2,故修改sample2不影响sample1.
传递sample1给test函数,然后在函数体内修改其第一个元素。之后打印sample1验证是否有影响,当然也没有。原因是一样的,当sample1作为参数传递给test时,sample1的拷贝被创建并传入,因此修改不会影响原来sample1.
2. 拷贝slice
Golang内置包提供copy函数能够拷贝slice,函数前面如下,其返回拷贝元素个数:
func copy(dst, src []Type) int
使用copy函数需要考虑两种情况:
如果src长度大于dst,那么仅拷贝dst长度个元素
如果dst长度大于src,那么仅拷贝src长度个元素
总结为拷贝两者最小长度元素:min(src,dst)
需要注意的是,一旦拷贝完成,对目标的修改不会影响源,反之亦然。
我们也通过示例说明:
package main
import "fmt"
func main() {
src := []int{1, 2, 3, 4, 5}
dst := make([]int, 5)
numberOfElementsCopied := copy(dst, src)
fmt.Printf("Number Of Elements Copied: %d\n", numberOfElementsCopied)
fmt.Printf("dst: %v\n", dst)
fmt.Printf("src: %v\n", src)
//After changing numbers2
dst[0] = 10
fmt.Println("\nAfter changing dst")
fmt.Printf("dst: %v\n", dst)
fmt.Printf("src: %v\n", src)
}
输出如下:
Number Of Elements Copied: 5
dst: [1 2 3 4 5]
src: [1 2 3 4 5]
After changing dst
dst: [10 2 3 4 5]
src: [1 2 3 4 5]
3. 总结
本文介绍了Go Array和Slice直接拷贝。Array是值类型直接赋值即拷贝,Slice是引用类型,直接赋值是指针会影响源Slice,但可以通过内置copy函数实现赋值功能。
补充:golang字节数组拷贝BlockCopy函数实现
在C#中,Buffer.BlockCopy(Array, Int32, Array, Int32, Int32) 函数使用比较广泛,其含义:
将指定数目的字节从起始于特定偏移量的源数组复制到起始于特定偏移量的目标数组。
参数 src Array 源缓冲区。 srcOffset Int32 src 中的字节偏移量,从零开始。 dst Array 目标缓冲区。 dstOffset Int32 dst 中的字节偏移量,从零开始。 count Int32 要复制的字节数。
go语言中实现如下:
func blockCopy(src []byte, srcOffset int, dst []byte, dstOffset, count int) (bool, error) {
srcLen := len(src)
if srcOffset > srcLen || count > srcLen || srcOffset+count > srcLen {
return false, errors.New("源缓冲区 索引超出范围")
}
dstLen := len(dst)
if dstOffset > dstLen || count > dstLen || dstOffset+count > dstLen {
return false, errors.New("目标缓冲区 索引超出范围")
}
index := 0
for i := srcOffset; i < srcOffset+count; i++ {
dst[dstOffset+index] = src[srcOffset+index]
index++
}
return true, nil
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持asp之家。如有错误或未考虑完全的地方,望不吝赐教。
来源:https://blog.csdn.net/neweastsun/article/details/106311321
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
怎么写好一份图形界面设计师简历
python Requsets下载开源网站的代码(带索引 数据)
Google谷歌的CSS前景图片合并技术
![](https://img.aspxhome.com/file/UploadPic/20097/13/82009621221830-30s.png)
Java 使用正则表达式对象实现正则的获取功能
Golang最大递减数算法问题分析
在python代码中加入环境变量的语句操作
![](https://img.aspxhome.com/file/2023/0/97050_0s.jpg)
多线程爬虫批量下载pcgame图片url 保存为xml的实现代码
小记一次mysql主从配置解决方案
![](https://img.aspxhome.com/file/2023/1/128071_0s.png)
VS自带的SQL server修改密码并连接使用
js:校验IPv6地址的正则表达式
asp如何显示一个等待或欢迎信息?
MYSQL中binlog优化的一些思考汇总
![](https://img.aspxhome.com/file/2023/3/96493_0s.jpg)
基于Python实现骰子小游戏
![](https://img.aspxhome.com/file/2023/3/128443_0s.jpg)
SQL Server2005下的安全操作技巧分享
PyTorch之nn.ReLU与F.ReLU的区别介绍
Windows10下安装解压版MySQL教程图文详解
![](https://img.aspxhome.com/file/2023/4/80004_0s.png)
详解如何基于Pyecharts绘制常见的直角坐标系图表
![](https://img.aspxhome.com/file/2023/4/71424_0s.png)
MySQL常用命令与内部组件及SQL优化详情
![](https://img.aspxhome.com/file/2023/1/111381_0s.png)
微信小程序分享海报生成的实现方法
![](https://img.aspxhome.com/file/2023/0/129590_0s.jpg)