golang copy函数使用的坑

 更新时间:2023年04月03日 15:11:57   作者:Robin92  
本文主要介绍了golang copy函数使用的坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

之前用 copy 不多,本以为它是个很方便的函数,没想到在做练习题时竟还是被它坑了。是我对他期望太多了。

func copy(dst, src []Type) int

基本认识:

  • 它只能用于切片,不能用于 map 等任何其他类型
  • 它返回结果为一个 int 型值,表示 copy 的长度

坑位一:切片 dst 需要先初始化长度

不是你定义好类型,就能将 src 完全 copy 到 dst 的,你需要初始化长度。

  • 如果 dst 长度小于 src 的长度,则 copy 部分;
  • 如果大于,则全部拷贝过来,只是没占满 dst 的坑位而已;
  • 相等时刚好不多不少 copy 过来。

坑位二:源切片中元素类型为引用类型时,拷贝的是引用

由于只 copy 切片中的元素,所以如果切片元素的类型是引用类型,那么 copy 的也将是个引用。

如下面例子,matA 和 matB 地址不一样,但 matA[0] 和 matB[0] 的地址是一样的。

func wrongCopyMatrix() {
    matA := [][]int{
        {0, 1, 1, 0},
        {0, 1, 1, 1},
        {1, 1, 1, 0},
    }
    matB := make([][]int, len(matA))
    copy(matB, matA)
    fmt.Printf("%p, %p\n", matA, matA[0]) // 0xc0000c0000, 0xc0000c2000
    fmt.Printf("%p, %p\n", matB, matB[0]) // 0xc0000c0050, 0xc0000c2000
}

如果想 copy 多维切片中的每一个切片类型的元素,那么你需要将每个切片元素进行 初始化 并 拷贝。注意是两步:先 初始化,再 拷贝。

正确的拷贝一个多维数组:

func rightCopyMatrix() {
    matA := [][]int{
        {0, 1, 1, 0},
        {0, 1, 1, 1},
        {1, 1, 1, 0},
    }
    matB := make([][]int, len(matA))
    for i := range matA {
        matB[i] = make([]int, len(matA[i])) // 注意初始化长度
        copy(matB[i], matA[i])
    }
    fmt.Printf("%p, %p\n", matA, matA[0]) // 0xc00005c050, 0xc000018560
    fmt.Printf("%p, %p\n", matB, matB[0]) // 0xc00005c0a0, 0xc0000185c0
}

到此这篇关于golang copy函数使用的坑的文章就介绍到这了,更多相关golang copy函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言编译程序从后台运行,不出现dos窗口的操作

    Go语言编译程序从后台运行,不出现dos窗口的操作

    这篇文章主要介绍了Go语言编译程序从后台运行,不出现dos窗口的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • 浅谈用Go构建不可变的数据结构的方法

    浅谈用Go构建不可变的数据结构的方法

    这篇文章主要介绍了用Go构建不可变的数据结构的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • goland 实现websocket server的示例代码

    goland 实现websocket server的示例代码

    本文主要介绍了goland 实现websocket server的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • go defer避坑指南之拆解延迟语句

    go defer避坑指南之拆解延迟语句

    这篇文章主要为大家详细介绍了go defer避坑指南之如何拆解延迟语句,掌握正确使用方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • Linux环境下编译并运行go项目的全过程

    Linux环境下编译并运行go项目的全过程

    Go语言是Google的开源编程语言,广泛应用于云计算、分布式系统开发等领域,在Linux上也有大量的应用场景,这篇文章主要给大家介绍了关于Linux环境下编译并运行go项目的相关资料,需要的朋友可以参考下
    2023-11-11
  • go语言规范RESTful API业务错误处理

    go语言规范RESTful API业务错误处理

    这篇文章主要为大家介绍了go语言规范RESTful API业务错误处理方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Go利用反射reflect实现获取接口变量信息

    Go利用反射reflect实现获取接口变量信息

    反射是通过实体对象获取反射对象(Value、Type),然后可以操作相应的方法。本文将利用Go语言中的反射reflect实现获取接口变量信息,需要的可以参考一下
    2022-05-05
  • GORM不定参数的用法最佳实践

    GORM不定参数的用法最佳实践

    这篇文章主要为大家介绍了GORM不定参数的用法最佳实践,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • golang xorm 自定义日志记录器之使用zap实现日志输出、切割日志(最新)

    golang xorm 自定义日志记录器之使用zap实现日志输出、切割日志(最新)

    这篇文章主要介绍了golang xorm 自定义日志记录器,使用zap实现日志输出、切割日志,包括连接postgresql数据库的操作方法及 zap日志工具 ,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • go实现Redis读写分离示例详解

    go实现Redis读写分离示例详解

    本篇文章将介绍Redis通信协议RESP, 而后在使用go来编写一个中间件,从而来完成Redis读写分离,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08

最新评论