`

Golang 把数组传递给函数

 
阅读更多

在 Golang 中数组是一个值类型,所有的值类型变量在赋值和作为参数传递时都将产生一次复制操作。如果直接将数组作为函数的参数,则在函数调用时数组会被复制一份传递给函数。因此,在函数体中无法修改源数组的内容,因为函数内操作的只是源数组的一个副本。
如此一来,从内存和性能上来看,在函数间传递数组是一个开销很大的操作。因为无论这个数组有多长,都会完整复制,并传递给函数。下面的 demo 中会声明一个包含 100 万个 int64 类型元素的数组,这会消耗掉 8MB 的内存:

func showArray(array [1e6]int64){
    // do something
}
var arr [1e6]int64
showArray(arr)

每次函数 showArray 被调用时,必须在栈上分配 8MB 的内存。之后整个数组的值(8MB 内存) 被复制到刚刚分配的内存中。虽然 Golang 的运行时会自动处理这个复制操作,但这样做的效率实在是太低了,也太耗费内存!合理且高效的方式是只传入指向数组的指针,这样只需复制 8 个字节的数据到函数的栈上就可以了:

func showArray(array *[1e6]int64){
    // do something
}
var arr [1e6]int64
showArray(&arr)

这段代码中的 showArray 函数接收一个指向包含 100 万个 int64 值的数组的指针,调用函数时传入的参数则是指向数组的指针。现在只需在栈上分配 8 个字节的内存给这个指针就行了。
这个方法能够更有效地利用内存,性能也更好。需要注意的是,此时在函数内外操作的都是同一个数组中的元素,会互相影响。

分享到:
评论

相关推荐

    Golang2-new.docx

    5.10.1. 把函数作为参数,传递给其它函数 134 5.10.2. 在其它函数中返回函数 134 5.11. 闭包 135 5.12. 头等函数的实际用途 137 6. 微服务创建 140 6.1. 使用net/http创建简单的web server 140 6.2. 读写JSON ...

    深入解析golang编程中函数的用法

    函数是一组一起执行任务的...例如,如果一个字符串传递给它,它会返回字符串的长度以字节为单位,如果一个数组传递给它,它就会返回数组的长度为它所拥有元素的个数。 函数称为具有各种名字等的方法或子例程或程序等。

    深入理解Go语言中的数组和切片

    数组是值类型,将一个数组赋值给另一个数组时,传递的是一份拷贝。 切片是引用类型,切片包装的数组称为该切片的底层数组。 我们来看一段代码 //a是一个数组,注意数组是一个固定长度的,初始化时候必须要指定...

    Go语言中的复合类型详细介绍

    golang复合类型包括:结构体、数组、切片、Maps。 1、数组 数组 golang中的数组与C语言中的数组差异很...你可以获得数组的地址,并生成一个指向数组的指针(例如,将其高效地传递给函数): 代码如下: func f(a [3]int)

    Golang学习笔记(四):array、slice、map

    如果作为函数的参数类型,则在函数调用时参数发生数据复制,在函数体中无法修改传入数组的内容 数组相等用 = != 比较,不能用 < > 1.声明&赋值 初始化 语法 代码如下: var VarName [n]type // n>=0 e.g. var a ...

    maxima-tests:Golang面试问题

    如何在Golang中创建多维数组我需要通过切片传递给函数吗? Golang运行时中发生了什么? goroutine和系统流程之间有什么区别? 在运行Golang程序时如何限制每个系统的线程数,是否可以将它们限制为1个线程? 什么是...

    asm2go:根据本机汇编代码自动生成golang汇编文件

    Go中的参数调用约定将参数放置在堆栈上,因此您应编写汇编代码以引用堆栈以访问提供给函数的参数。 这可能与通常执行的结果不匹配,例如有时使用寄存器代替传递参数,但是引用堆栈似乎是执行此操作的最佳方法。 尚...

    Go语言入门指南大纲及框架建议:轻松掌握Go语言学习秘诀.docx

     函数参数传递(值传递与引用传递)  函数返回值  匿名函数(闭包)  方法与接收者 7. 数组与切片  数组的定义与使用  切片的定义与操作  切片的扩容与截断  append函数的使用  数组与切片的转

    详细介绍了Go基础分片操作,超级简单易学

    Go语言中的切片(Slice)是一种动态数组,它为内置数组类型提供了更加灵活的用法。切片操作是Go编程中非常基础且常用的技能,以下是对Go切片...8. **切片作为函数参数**:切片可以作为参数传递给函数,由于切片是引用

    golang源码分析–slice

    (注意:切片传递的是指针的拷贝值,所以可以在函数里面修改指针指向的值,对外有影响) 切片的自动增长是通过append()函数来实现的 切片的底层内存也是在连续块中分配的,所以切片还能获得索引,迭代以及为垃圾回收...

    collection:去收集包以进行禁食编码

    collection Collection包目标是...增加了对int32的支持,增加了延迟加载,增加了Copy函数,增加了compare从ICollection传递到IMix,使用快排加速了Sort方法 1.0.1 第一次发布 go get github.com/jianfengye/collecti

    leetcode296-leetcode-in-py-and-go:Go中的Leetcode

    Golang 中的 Leetcode 算法程序解决方案的架子 3:一环解决; 开始索引 4: 2个排序数组的中位数,m = min(len(arr1)-1, (kth-1)/2)!!! 5:通过expand处理“aaaaaaa” 10:正则表达式。 注意 ("", "a ") -> 反转并...

Global site tag (gtag.js) - Google Analytics