go语言中切片与内存复制 memcpy 的实现操作

Go 语言原则上不支持内存的直接操作访问,但是提供了切片功能。

最初我以为切片就是动态数组,实际程序设计过程中发现,切片是提供数组一个内存片段的一个合法的手段,利用切片功能,实际上我们可以自由访问数组的任何一个片段,因而可以借助 copy 函数,实现内存复制。

不同类型之间的数据复制,可以借助 unsafe 取出变量地址,类型转换为数组后,利用数组切片,实现内存复制。

不罗嗦了,示例代码如下:

package main
import (
    "fmt"
    "unsafe"
)
func main() {
    //数组之间的数据复制
    var a = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    var b = [10]int{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
    copy(a[5:8], b[0:])
    fmt.Println(a, b)
    //不同数据类型之间的复制
    var c uint32 = 0x04030201
    var d [4]byte
    p := unsafe.Pointer(&c)
    q := (*[4]byte)(p)
    copy(d[0:], (*q)[0:])
    fmt.Println(d)
}

运行结果:

[0 1 2 3 4 -1 -1 -1 8 9] [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1]

[1 2 3 4]

补充:go语言之切片复制与追加

看代码吧~

package main
import (
 "fmt"
)
func main() {
 // copy示例
 // 创建一个新的更大的切片并把原分片的内容都拷贝过来
 sl_from := []int{1, 2, 3}
 sl_to := make([]int, 10)
 n := copy(sl_to, sl_from)
 fmt.Println("num:", n, "items", sl_to)
 // append追加元素
 // append 方法将0个或多个具有相同类型 s 的元素追加到切片后面并且返回新的切片
 // 追加的元素必须和原切片的元素同类型
 // 如果 s 的容量不足以存储新增元素,append 会分配新的切片来保证已有切片元素和新增元素的存储
 sl_a := []int{1, 2, 3}
 sl_a = append(sl_a, 4, 5, 6)
 fmt.Println(sl_a)
 // append 方法追加一个切片
 var sl_b []int
 sl_c := []int{1, 2, 3}
 sl_b = append(sl_b, sl_c...)
 fmt.Println(sl_b)
 // 将一个元素快速转为对应切片类型
 x := 5
 Test([]int{x})
}
func Test(x []int)  {
 fmt.Println(x)
}

运行结果:

num: 3 items [1 2 3 0 0 0 0 0 0 0]

[1 2 3 4 5 6]

[1 2 3]

[5]

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • 解决golang内存溢出的方法

    最近在项目中出现golang内存溢出的问题,master刚开始运行时只有10多M,运行几天后,竟然达到了10多个G.而且到凌晨流量变少内存也没有明显降低,内存状态呈现一种很不健康的曲线. 像这种情况肯定是golang内存溢出了,为此我持续排查了两天,终于找到问题所在,特此记录下. 准备工作 一台较好的环境测试机,单台运行无污染. 压测工具,无论服务是http还是websocket服务,都必须准备好压测工具模拟最真实的用户场景. 将master引入net/http/pprof包,通过http访问获

  • Go语言中的内存布局详解

    一.go语言内存布局 想象一下,你有一个如下的结构体. 复制代码 代码如下: type MyData struct {         aByte   byte         aShort  int16         anInt32 int32         aSlice  []byte } 那么这个结构体究竟是什么呢? 从根本上说,它描述了如何在内存中布局数据. 这是什么意思?编译器又是如何展现出来呢? 我们来看一下. 首先让我们使用反射来检查结构中的字段. 二.反射之上 下面是一些使用

  • Go pprof内存指标含义备忘录及案例分析

    最近组内一些Go服务碰到内存相关的问题,所以今天抽时间看了下Go pprof内存指标的含义,为后续查问题做准备. 内容主要来自于Go代码中对这些字段的注释,加自己的理解.理解不对的地方欢迎指正. // https://github.com/golang/go/blob/master/src/runtime/mstats.go#L150 // 总共从OS申请的字节数 // 是下面各种XxxSys指标的总和.包含运行时的heap.stack和其他内部数据结构的总和. // 它是虚拟内存空间.不一定全

  • golang切片内存应用技巧详解

    在 Go 语言中切片是使用非常频繁的一种聚合类型,它代表变长的序列,底层引用一个数组对象.一个切片由三个部分构成:指针.长度和容量.指针指向该切片自己第一个元素对应的底层数组元素的内存地址. 切片的类型声明如下: type slice struct { array unsafe.Pointer len int cap int } 多个切片之间可以共享底层数组的数据,并且引用的数组区间可能重叠.利用切片 的这个特性我们可以在原有内存空间中对切片进行反转.筛选和去重等操作,这样就不用声明一个指向新内

  • go语言中切片与内存复制 memcpy 的实现操作

    Go 语言原则上不支持内存的直接操作访问,但是提供了切片功能. 最初我以为切片就是动态数组,实际程序设计过程中发现,切片是提供数组一个内存片段的一个合法的手段,利用切片功能,实际上我们可以自由访问数组的任何一个片段,因而可以借助 copy 函数,实现内存复制. 不同类型之间的数据复制,可以借助 unsafe 取出变量地址,类型转换为数组后,利用数组切片,实现内存复制. 不罗嗦了,示例代码如下: package main import ( "fmt" "unsafe"

  • 详解Go语言中切片的长度与容量的区别

    目录 切片的声明 切片的长度和容量 切片追加元素后长度和容量的变化 append 函数 切片的源代码学习 切片的结构体 切片的扩容 总结 切片的声明 切片可以看成是数组的引用(实际上切片的底层数据结构确实是数组).在 Go 中,每个数组的大小是固定的,不能随意改变大小,切片可以为数组提供动态增长和缩小的需求,但其本身并不存储任何数据. // 数组的声明 var a [5]int //只指定长度,元素初始化为默认值0 var a [5]int{1,2,3,4,5} // 切片的声明 // 方法1:

  • go语言中切片的长度和容量的区别

    切片的长度,显而易见的就是元素的个数,根据元素的个数进行返回具体的长度. 切片的长度,更像是一个警戒值,如果长度与容量相等,就会进行容量的扩容,比如 des :=make([]int , 3 , 5) //此时,长度为3,容量为5,但是如果使用append(), //切片长度会变为4,再次使用append()切片长度变为5. //此时,切片长度与容量相同,此时,切片的容量增大变为cap = len*2 也就是通过一个容量设警戒值,如果等于警戒值,就会自动将切片进行扩容 补充:Go语言中切片的长度

  • 关于C语言中数据在内存中的存储详解

    前言 1. 数据类型详细介绍 2. 整形在内存中的存储:原码.反码.补码 3. 大小端字节序介绍及判断 4. 浮点型在内存中的存储解析 一.数据类型介绍 1.类型的基本归类 1.整形家族 char unsigned char signed char short unsigned short [int] signed short [int] int unsigned int signed int long unsigned long [int] signed long [int] 2.浮点型家族

  • C语言中关于动态内存分配的详解

    目录 一.malloc 与free函数 二.calloc 三.realloc 四.常见的动态内存的错误 [C语言]动态内存分配 本期,我们将讲解malloc.calloc.realloc以及free函数. 这是个动态内存分配函数的头文件都是 <stdlib.h>. c语言中动态分配内存的函数,可能有些初学c语言的人不免要问了:我们为什么要通过函数来实现动态分配内存呢? 首先让我们熟悉一下计算机的内存吧!在计算机的系统中大致有这四个内存区域: 1)栈:在栈里面储存一些我们定义的局部变量以及形参(

  • 深入了解C语言中的动态内存分配

    目录 什么是动态内存分配 如何进行动态内存分配 首先我要介绍两个函数 malloc 和 free 第二个开辟空间的动态内存分配的函数 calloc 大小修改函数realloc 今天我们来学习一下C语言中的动态内存分配 开始学习吧 什么是动态内存分配 我们目前已经知道的内存开辟的方式有: int val = 20;//在栈上开辟四个字节. char arr[10] = { 0 };//在栈上开辟十个字节的连续空间 但是上述空间的开辟方式有两个特点: 1.空间开辟的大小是固定的 2.数组在申明的时候

  • go语言中切片Slice与数组Array对比以及panic: runtime error: index out of range问题解决

    目录 前言 一.go slice是什么 二.go slice实战案例 1.slice创建.使用 2.slice的长度和容量概念理解 3. 切片扩容及slice panic: runtime error: index out of range 附:go 判断数组下标是否存在 总结 前言 在go语言的学习历程当中,slice数据类型引起了我的好奇心.为啥不直接使用Slice,是人性的扭曲还是道德的沦丧~,下面让我们一探究竟~~ 一.go slice是什么 go语言中的slice是一个基于Array封

  • 一文带你深入了解Go语言中切片的奥秘

    目录 Go语言基础三 切片的定义 创建切片的方式 切片初始化 Go语言基础三 切片的定义 1. 切片:切片是数组的一个引用,因此切片是引用类型.但自身是结构体,值拷贝传递. 2. 切片的长度可以改变,因此,切片是一个可变的数组. 3. 切片遍历方式和数组一样,可以用len()求长度.表示可用元素数量,读写操作不能超过该限制. 4. cap可以求出slice最大扩张容量,不能超出数组限制.0 <= len(slice) <= len(array),其中array是slice引用的数组. 5. 切

  • 详解C语言中的动态内存管理

    目录 一.动态内存管理 1.1为什么要有动态内存管理 1.2动态内存介绍 1.3常见的动态内存错误 一.动态内存管理 1.1为什么要有动态内存管理 1.1.1  在c语言中我们普通的内存开辟是直接在栈上进行开辟的 int i = 20;//在栈空间上开辟四个字节 int arr[10]={0}; //在栈中连续开辟四十个字节 这样开辟的特点是: (1)他所开辟的空间是固定的 (2)数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配 但对于空间的需求,我们有的时候并不知道,有可能空间

  • 一文带你了解C语言中的动态内存管理函数

    目录 1.什么是动态内存管理 2.为什么要有动态内存管理 3.如何进行动态内存管理 3.1 malloc 3.2 free 3.3 calloc 3.4 realloc 总结 1.什么是动态内存管理 平时我们写代码,一种非常常见的写法是: int a = 0; // 创建一个变量 int arr[10] = {0}; // 创建一个数组 当你创建变量a的时候,其实是向内存中申请了4个字节的空间来存放一个整数.而当你创建数组arr的时候,是向内存中申请了40个字节的空间来存放10个整数.当你这么写

随机推荐