数组和切片作为函数参数传递时的行为差异
- 数组:
- 数组作为函数参数传递时,是值传递。这意味着函数接收的是原数组的一个副本,对副本的任何修改都不会影响原数组。
- 例如:
package main
import "fmt"
func modifyArray(arr [3]int) {
arr[0] = 100
}
func main() {
original := [3]int{1, 2, 3}
modifyArray(original)
fmt.Println(original)
}
- 在上述代码中,
modifyArray
函数接收一个数组副本并修改其第一个元素为100,但原数组original
并没有改变,打印结果为[1 2 3]
。
- 切片:
- 切片作为函数参数传递时,是引用传递。函数接收的是切片的引用,对切片的修改会反映到原切片上。
- 例如:
package main
import "fmt"
func modifySlice(slice []int) {
slice[0] = 100
}
func main() {
original := []int{1, 2, 3}
modifySlice(original)
fmt.Println(original)
}
- 在这段代码中,
modifySlice
函数接收切片original
的引用并修改其第一个元素为100,原切片original
也会被修改,打印结果为[100 2 3]
。
根据差异选择合适的数据结构提高程序性能
- 如果不需要修改原数据且数据量不大:
- 选择数组。因为数组在传递时虽然是值传递会复制数据,但如果数据量小,复制的开销相对较小,并且数组的内存布局是连续的,在一些对缓存友好的场景下有一定优势。例如,一些简单的统计函数,只需要对固定大小的数据进行读取操作,不需要修改原数据。
- 如果需要修改原数据或者数据量较大:
- 选择切片。由于切片是引用传递,不会复制大量数据,在传递大的数据集合时,内存和性能开销都比数组小很多。例如,在处理大数据集的排序、筛选等操作时,使用切片可以避免大量的数据复制,提高程序性能。