首页 > 快讯 >

Go语言copy()实现切片复制

2023-04-04 05:48:36 来源:脚本之家


(资料图片)

Go语言的内置函数 copy() 可以将一个数组切片复制到另一个数组切片中,如果加入的两个数组切片不一样大,就会按照其中较小的那个数组切片的元素个数进行复制。

copy() 函数的使用格式如下:

copy( destSlice, srcSlice []T) int

其中 srcSlice 为数据来源切片,destSlice 为复制的目标(也就是将 srcSlice 复制到 destSlice),目标切片必须分配过空间且足够承载复制的元素个数,并且来源和目标的类型必须一致,copy() 函数的返回值表示实际发生复制的元素个数。

下面的代码展示了使用 copy() 函数将一个切片复制到另一个切片的过程:

slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{5, 4, 3}
copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中
copy(slice1, slice2) // 只会复制slice2的3个元素到slice1的前3个位置

虽然通过循环复制切片元素更直接,不过内置的 copy() 函数使用起来更加方便,copy() 函数的第一个参数是要复制的目标 slice,第二个参数是源 slice,两个 slice 可以共享同一个底层数组,甚至有重叠也没有问题。

【示例】通过代码演示对切片的引用和复制操作后对切片元素的影响。

package main
import "fmt"
func main() {
    // 设置元素数量为1000
    const elementCount = 1000
    // 预分配足够多的元素切片
    srcData := make([]int, elementCount)
    // 将切片赋值
    for i := 0; i < elementCount; i++ {
        srcData[i] = i
    }
    // 引用切片数据
    refData := srcData
    // 预分配足够多的元素切片
    copyData := make([]int, elementCount)
    // 将数据复制到新的切片空间中
    copy(copyData, srcData)
    // 修改原始数据的第一个元素
    srcData[0] = 999
    // 打印引用切片的第一个元素
    fmt.Println(refData[0])
    // 打印复制切片的第一个和最后一个元素
    fmt.Println(copyData[0], copyData[elementCount-1])
    // 复制原始数据从4到6(不包含)
    copy(copyData, srcData[4:6])
    for i := 0; i < 5; i++ {
        fmt.Printf("%d ", copyData[i])
    }
}

代码说明如下:

第 8 行,定义元素总量为 1000。第 11 行,预分配拥有 1000 个元素的整型切片,这个切片将作为原始数据。第 14~16 行,将 srcData 填充 0~999 的整型值。第 19 行,将 refData 引用 srcData,切片不会因为等号操作进行元素的复制。第 22 行,预分配与 srcData 等大(大小相等)、同类型的切片 copyData。第 24 行,使用 copy() 函数将原始数据复制到 copyData 切片空间中。第 27 行,修改原始数据的第一个元素为 999。第 30 行,引用数据的第一个元素将会发生变化。第 33 行,打印复制数据的首位数据,由于数据是复制的,因此不会发生变化。第 36 行,将 srcData 的局部数据复制到 copyData 中。第 38~40 行,打印复制局部数据后的 copyData 元素。

补:从切片中删除元素

package main

import "fmt"


//Go语言并没有对删除切片元素提供专用的语法或者接口,需要使用切片本身的特性来删除元素,
//Go语言中删除切片元素的本质是,以被删除元素为分界点,将前后两个部分的内存重新连接起来。
// 根据要删除元素的位置有三种情况,分别是从开头位置删除、从中间位置删除和从尾部删除,其中删除切片尾部的元素速度最快。

func main()  {
    //用=号的话必须先var声明
    var a [] int
    a=[]int{4,5,6}
    fmt.Println(a)    //[4 5 6]
    //用:=是声明并赋值,并且系统自动判断类型,不需要var关键字
    b:=[]int{7,8,9}
    fmt.Println(b)  //[7 8 9]

    //1.利用切片的特性来删除元素
    a=a[1:]  //取索引1以后的值(包含索引1)即删除a[0]
    //a=a[N:]  //删除开头n个元素
    fmt.Println(a)  //[5 6]


    //2.也可以不移动数据指针,但是将后面的数据向开头移动,可以用 append 原地完成
    // 所谓原地完成是指在原有的切片数据对应的内存区间内完成,不会导致内存空间结构的变化:
    fmt.Println(a[:0])  //取到a[0]结尾且不包含a[0],即为[]
    a = append(a[:0],a[1:]...)//在尾部追加a[1:],即a[n:]删除前n个元素
    fmt.Println(a)   //[6]

    //3.copy()函数删除元素
    //copy把b[1:]复制给b,返回复制后的len(b),多此一举,和b[1:]结果一样
    b=b[:copy(b,b[1:])]
    fmt.Println(b)    //[8 9]


    //4.从中间位置删除
    //对于删除中间的元素,需要对剩余的元素进行一次整体挪动,同样可以用append或copy原地完成


    //append操作
    c:=[]int{1,2,3,4,5}
    //c=append(c[:i],c[i+1:]...)  删除中间一个元素:(c[i])
    //c=append(c[:i],c[i+N:]...)  删除中间N个元素:(c[i:I+N-1])
    //先取c[:1]之前的数据,在追加c[2:]之后的数据,即删除c[1]
    c=append(c[:1],c[2:]...)
    fmt.Println(c) //[1 3 4 5]

    //copy操作
    d:=[]int{1,2,3,4,5}
    //d=d[:i+copy(d[i:],d[i+1:])]  删除中间一个元素(d[i]),因为从d[i:]开始的,所以i是之前元素的个数
    //d=d[:i+copy(d[i:],d[i+N:])]  删除中间N个元素

    //先将d[2:]之后的数据copy给d[1:]之后的数据,即删除了d[1]数据,并返回len(d[2:]),再连接d[1]之前的数据
    d=d[:1+copy(d[1:],d[2:])]   //删除中间一个元素(d[1])
    fmt.Println(d)//[1 3 4 5]


    //5.从尾部删除

    g:=[]int{1,2,3,4}
    g=g[:len(g)-1]   //删除尾部一个元素
    //g=g[:len(g)-N] //删除尾部N个元素
    fmt.Println(g)   //[1 2 3]


    index()
}


//删除切片指定位置的元素
func index()  {
    str:=[]string{"a","b","c","d"}
    //指定删除索引
    index:=2
    //查看删除索引之前的元素,删除索引之后的元素
    fmt.Println(str[:index],str[index+1:])   //[a b] [d]
    //将删除点前后元素连接起来
    str=append(str[:index],str[index+1:]...)

    fmt.Println(str)   //[a b d]

到此这篇关于Go语言copy()实现切片复制的文章就介绍到这了,更多相关Go 切片复制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

上一篇:

下一篇:

x
推荐阅读

Go语言copy()实现切片复制

英诗的境界_关于英诗的境界的简介-全球即时看

头条:割双眼皮后眼角增生能彻底消失吗

包头唐悦礼品主要经营_焦点

国家肉鸽良种繁育标准化示范区项目启动_天天新要闻

趣头条黯然退市,但已无人关心

环球热讯:开立医疗:医用内窥镜摄像系统取得医疗器械注册证

海螺怎么吃?

揭西县生活垃圾环保处理中心(揭西县环保能源产业园)项目施工总承包工程招标!

4月3日东北地区地炼汽柴油报价上涨

今年第一季度旅游市场“开门红”,你都去了哪里?-世界要闻

环球今日讯!护林员常态化巡护 上千只苍鹭在四川广元“安家”

每日简讯:钟楚红同框周润发老婆,女明星和富家千金的气质差别,还真不一样

世界观点:旅美大熊猫丫丫回国进入倒计时!8日起起居全部移交中方人员

报道:黄渤在三亚炫富的行为引发争议,但背后的故事却让人深思

4月投资策略

环球动态:二手房交易可以“带押过户”

天津口岸今年最大一批进口铜精矿靠港 新模式通关省时3至4天

博时、华安、中金、红土创新“饮头啖汤” 首批四家公募REITs扩募获批

第二十二届环青海湖国际公路自行车赛将于7月8日揭幕 观点

京津冀一体化又有新进展!看病“一卡通行”,三地全面取消异地就医备案 全球实时

设立清明志愿服务岗 八宝山殡仪馆推多项惠民便民措施

太阳报揭秘格拉利什代言费:彪马1000万镑,古驰1000万镑|天天速读

刷牙竟刷出牙周病?可能是牙膏惹的祸 世界速看

国乒官宣13人大名单!3大世界冠军领衔,为世乒赛热身

环球速递!西部车市总评榜获奖车型公布,西部消费者购车指南就看这

环球快看:淮南矿务局公积金查询_淮南矿务局

二级建造师工作年限证明怎么开_二级建造师工作证明

焦点短讯!顺丰控股控股股东向子公司深圳玮顺转让1亿股 代价49.68亿

中国三迪:2022年总收入约为人民币34.49亿元_天天速看

寻求“建交”加纳被掮客骗数亿元?台当局否认,学者:要改善两岸关系 环球最新

商务部:推进内外贸一体化是构建新发展格局的内在要求,是推进贸易强国的重要任务-每日快报

中信保诚基金王睿:消费和顺周期行业基本面改善的确定性较高

不动产“带押过户”将全面推广:目前已有百余市先行“试水”

《时空勇士》高清版steam/ps发售日公开!能免费试玩 焦点热闻

北京围绕今年重点工作任务邀海内外人士提建议

江油外国语学校长地址 当前速看

手机美图秀秀怎么抠图保存(手机美图秀秀怎么抠图)

全国网友日均刷短视频超2.5小时 网络直播用户规模超7.5亿-全球时讯

今日热门!海通国际给予比亚迪优于大市评级,全年业绩维持高增,国内外市场全面突围剑指全球销冠

无编人员清理速度真的好快!第一批清理打发走34个派遣工

天天资讯:《十月围城》中原型人物,“废纸堆”中惊见辛亥革命义士签名

世界热推荐:这些地方暖到破纪录 强冷空气到货后气温掉回个位数

快资讯:村民向政府的诉求范文(汇总3篇)

手机发布会送什么礼品-热点聚焦

【独家焦点】通州区“文化餐桌”上新,宋庄两座类博物馆正式挂牌

3月31日00时贵州遵义防疫最新消息信息 贵州遵义疫情最新通报今天

从毒瘤到球队领袖,NBA最励志球星诞生!原来小卡和老詹真不一样

环球今日报丨邮局是事业单位还是国企?邮局营业时间

环球百事通!微盟发布2022年报:总营收18亿元,下半年亏损环比收窄0.8亿