Golang面试题-切片Slice和数组比较

Go 数组是值类型,赋值和函数传参操作都会复制整个数组数据。

切片slice是引用传递,不需要额外的内存,而切片本身是一种数组指针的封装。

下面是一个数组传参测试输出:

func Test1() {
	array1 := [2]int{100, 200}
	array2 := array1

	fmt.Printf("array1: %p, %v
", &array1, array1)
	fmt.Printf("array2: %p, %v
", &array2, array2)

	printArray(array1)
}

func printArray(x [2]int) {
	fmt.Printf("func array: %p, %v
", &x, x)
}
array1: 0xc000271590, [100 200]
array2: 0xc0002715a0, [100 200]
func array: 0xc0002715d0, [100 200]

假想每次传参都用数组,那么每次数组都要被复制一遍。这样会消耗掉大量的内存。于是乎有人想到,函数传参用数组的指针。

但是传递数组指针会有一个弊端,万一原数组的指针指向更改了,那么函数里面的指针指向都会跟着更改。

所以说把第一个大数组传递给函数会消耗很多内存,采用切片的方式传参可以避免上述问题。切片是引用传递,所以它们不需要使用额外的内存并且比使用数组更有效率。

当然也有特例,借用一个

package main

import "testing"

func array() [1024]int {
	var x [1024]int
	for i := 0; i < len(x); i++ {
		x[i] = i
	}
	return x
}

func slice() []int {
	x := make([]int, 1024)
	for i := 0; i < len(x); i++ {
		x[i] = i
	}
	return x
}

func BenchmarkArray(b *testing.B) {
	for i := 0; i < b.N; i++ {
		array()
	}
}

func BenchmarkSlice(b *testing.B) {
	for i := 0; i < b.N; i++ {
		slice()
	}
}
   func git:(main)   go test -bench . -benchmem -gcflags "-N -l"
goos: darwin
goarch: amd64
pkg: func
cpu: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
BenchmarkArray-4          339076              3028 ns/op               0 B/op          0 allocs/op
BenchmarkSlice-4          281892              4295 ns/op            8192 B/op          1 allocs/op
PASS
ok      func    4.364s

这样对比看来,并非所有时候都适合用切片代替数组,因为切片底层数组可能会在堆上分配内存,而且小数组在栈上拷贝的消耗也未必比make 消耗大。

展开阅读全文

页面更新:2024-03-08

标签:数组   切片   都会   赋值   特例   假想   指针   函数   消耗   内存

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top