Go 语言学习查缺补漏 ing Day9
Go 语言学习查缺补漏 ing Day9
一、又谈 defer 的执行顺序
请看下面这段代码:
程序运行结果是:
为什么呢?执行 f(3)时,这段代码会先执行 return 中的 n+2,然后执行 defer 语句,因为 defer 语句是先进后出,故先执行 defer f(),然后因为此时 f()未定义,所以会导致 panic 异常读书,不过,别急,我们下一个 defer 语句使用 recover()将异常回收了,然后 r += n,也就是 r 加 3,因为 r+8 未执行,所以和是 3+2+3=8.
二、切片底层数组的一个有关问题
再看下面这段代码:
你认为输出结果是什么?
下面是输出结果。你答对了吗?
答对的小伙伴可以看下一点啦~
答错的小伙伴来听我解释一下吧~
如果函数 change(s ...int)的参数类型使用...
,可以将 slice 切片传入而不会新建切片。这里第一次调用 change()函数前,创建的切片容量和长度是相等的,所以调用 change()函数后,切片进行扩容,会导致生成新的切片,8 也加在新的切片上,原来的切片不会发生变化。
这行代码使用[0:2]截取生成了一个新的切片,但是它的底层数组与之前的切片的底层数组是一样的,不过新切片的长度是 2,而之前切片的长度是 5.所以在这个切片上 append 元素我们打印旧切片 slice 能够看到,也就是:
然后我们一直截取一直增加,直到:
此时切片的容量和长度已经加到一致了,再 append 来添加元素就会导致扩容,而导致底层数组变化。所以再次打印 slice 切片,就会还是:
三、for...range 遍历数组与切片的区别
先来看一看运行结果:
我们可以看到,遍历时保存的 r 数组内的值与最终输出的数组不一致,我们前面的文章说过,这是因为 for...range 遍历数组时,会生成一个副本,然后遍历这个副本,所以我们在循环中修改数组的值并不会修改副本的值,所以导致两个数组结果不一致。
而切片就不一样了,我们来看一看切片会有什么运行结果:
这是运行结果:
我们可以看到两个是相同的,这是因为虽然是副本,但是指向的是同一个底层数组,因此修改副本的底层数组也会修改原切片的底层数组。
版权声明: 本文为 InfoQ 作者【Regan Yue】的原创文章。
原文链接:【http://xie.infoq.cn/article/f38c0ee14efd7e793c873ccb4】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论