怎么在Golang对Array和Slice进行拷贝
怎么在Golang对Array和Slice进行拷贝?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
golang的优点
golang是一种编译语言,可以将代码编译为机器代码,编译后的二进制文件可以直接部署到目标机器而无需额外的依赖,所以golang的性能优于其他的解释性语言,且可以在golang中使用goroutine来实现并发性,它提供了一个非常优雅的goroutine调度程序系统,可以很容易地生成数百万个goroutine。
1. 拷贝array
前面提及数组是值类型,所以数组变量名不是指向第一个元素的指针。事实上它表示整个数组,下面两者情况将自动创建数组:
数组变量赋值给另一个数组变量
数组变量传递作为函数参数
请看示例:
package mainimport "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, class="lazy" data-src []Type) int
使用copy函数需要考虑两种情况:
如果class="lazy" data-src长度大于dst,那么仅拷贝dst长度个元素
如果dst长度大于class="lazy" data-src,那么仅拷贝class="lazy" data-src长度个元素
总结为拷贝两者最小长度元素:min(class="lazy" data-src,dst)
需要注意的是,一旦拷贝完成,对目标的修改不会影响源,反之亦然。
我们也通过示例说明:
package mainimport "fmt"func main() { class="lazy" data-src := []int{1, 2, 3, 4, 5} dst := make([]int, 5) numberOfElementsCopied := copy(dst, class="lazy" data-src) fmt.Printf("Number Of Elements Copied: %d\n", numberOfElementsCopied) fmt.Printf("dst: %v\n", dst) fmt.Printf("class="lazy" data-src: %v\n", class="lazy" data-src) //After changing numbers2 dst[0] = 10 fmt.Println("\nAfter changing dst") fmt.Printf("dst: %v\n", dst) fmt.Printf("class="lazy" data-src: %v\n", class="lazy" data-src)}
输出如下:
Number Of Elements Copied: 5
dst: [1 2 3 4 5]
class="lazy" data-src: [1 2 3 4 5]
After changing dst
dst: [10 2 3 4 5]
class="lazy" data-src: [1 2 3 4 5]
3. 总结
本文介绍了Go Array和Slice直接拷贝。Array是值类型直接赋值即拷贝,Slice是引用类型,直接赋值是指针会影响源Slice,但可以通过内置copy函数实现赋值功能。
补充:golang字节数组拷贝BlockCopy函数实现
在C#中,Buffer.BlockCopy(Array, Int32, Array, Int32, Int32) 函数使用比较广泛,其含义:
将指定数目的字节从起始于特定偏移量的源数组复制到起始于特定偏移量的目标数组。
参数 class="lazy" data-src Array 源缓冲区。 class="lazy" data-srcOffset Int32 class="lazy" data-src 中的字节偏移量,从零开始。 dst Array 目标缓冲区。 dstOffset Int32 dst 中的字节偏移量,从零开始。 count Int32 要复制的字节数。
go语言中实现如下:
func blockCopy(class="lazy" data-src []byte, class="lazy" data-srcOffset int, dst []byte, dstOffset, count int) (bool, error) { class="lazy" data-srcLen := len(class="lazy" data-src) if class="lazy" data-srcOffset > class="lazy" data-srcLen || count > class="lazy" data-srcLen || class="lazy" data-srcOffset+count > class="lazy" data-srcLen { return false, errors.New("源缓冲区 索引超出范围") } dstLen := len(dst) if dstOffset > dstLen || count > dstLen || dstOffset+count > dstLen { return false, errors.New("目标缓冲区 索引超出范围") } index := 0 for i := class="lazy" data-srcOffset; i < class="lazy" data-srcOffset+count; i++ { dst[dstOffset+index] = class="lazy" data-src[class="lazy" data-srcOffset+index] index++ } return true, nil}
关于怎么在Golang对Array和Slice进行拷贝问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341