【Go面试题】关于 array 和 slice 一个问题

写在前面

最近有同学问我这个问题啊,以下两个函数输出了什么?

func arrayTest() {
    
    
	a := [3]int{
    
    1, 2, 3}
	for k, v := range a {
    
    
		if k == 0 {
    
    
			a[0], a[1] = 100, 200
		}
		a[k] = 100 + v
	}
	fmt.Println(a)
}
func sliceTest() {
    
    
	a := []int{
    
    1, 2, 3}
	for k, v := range a {
    
    
		if k == 0 {
    
    
			a[0], a[1] = 100, 200
		}
		a[k] = 100 + v
	}
	fmt.Println(a)
}

先给结论

  • 数组:[101,102,103]
  • 切片:[101,300,103]

题解

众所周知,Go里面都是值传递,就算是引用类型也是传地址。

我们先了解一下一些数据结构

队列:先进先出
栈:先进后出,在程序调用的时候从栈空间去分配
堆:在程序调用的时候从系统的内存区分配

值类型: 变量直接存储值,内容通常在栈中分配
引用类型: 变量存储的是一个地址,这个地址存储最终的值,内容通常在堆上分配,通过GC回收

那么Go的值传递和引用类型又有哪些?

值类型:基本数据类型intfloatboolstring数组struct
引用类型:指针slicemapchan 等都是引用类型

知道数组是值传递,切片是引用我们就清楚了。

数组只是传递值,相当于深拷贝,无论怎么改变都并不影响原值,而切片是传递地址,改变就会跟着改变

看看这个例子

var x[4]int = [4]int{
    
    1,2,3,4}
var y[4]int = x
fmt.Println(x,y)
y[0]=123
fmt.Println(x,y) 

结果

[1 2 3 4] [1 2 3 4]
[1 2 3 4] [123 2 3 4]

我们可以看到这个数组的改变并不影响原来的数组,那么当我们将这个数组变成切片的时候。

var x[]int = []int{
    
    1,2,3,4}
var y[]int = x
fmt.Println(x,y)
y[0]=123
fmt.Println(x,y) 

结果

[1 2 3 4] [1 2 3 4]
[123 2 3 4] [123 2 3 4]

当我们改变切片的时候,是都变了。

回到这道题上

那么我们知道 数组是值传递,切片是引用传递

func arrayTest() {
    
    
	a := [3]int{
    
    1, 2, 3} 	// 数组
	for k, v := range a {
    
     
		if k == 0 {
    
    
			a[0], a[1] = 100, 200 // 改变了
		}
		a[k] = 100 + v // 之后又改变了
	}
	fmt.Println(a)
}

所以上面的数组就可以理解为是临时改变了,但是原地址上面的还是原来的值

我们 debug 一下就更清楚了

  • 初始状态

在这里插入图片描述

  • 第一次改变

在这里插入图片描述
我们发现原来数组a的前两位已经发生了改变

  • 第二次改变

在这里插入图片描述

  • 第三次改变

在这里插入图片描述
其实我们把 k,v 打印出来就明显很多了,k v从始至终都没有改变过

在这里插入图片描述

那么换成切片是什么样子呢?

func sliceTest() {
    
    
	a := []int{
    
    1, 2, 3}
	for k, v := range a {
    
    
		if k == 0 {
    
    
			a[0], a[1] = 100, 200
		}
		a[k] = 100 + v
	}
	fmt.Println(a)
}

同样debug一下,就很清楚了

在这里插入图片描述

注意第一次循环的话,这个v的值是1!!因为已经定下来了

在这里插入图片描述
切片的值也已经变了,但是此时v是1!所以这个a[0]=100+1 。 而当下一个之后v就变成200了!!
所以这个300就是这样来的!

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

所以这里要考察的是go的值传递和引用类型的区别。

参考链接

array与slice的传递方式

猜你喜欢

转载自blog.csdn.net/weixin_45304503/article/details/123439027