开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第33天,点击查看活动详情
今天来学习下Go常见的习题问题(十),也是面试中可能会遇到的,让我们来一起学习吧~
循环次数
观察下列代码,判断是否会出现死循环?
func main() {
v := []int{1, 2, 3}
for i := range v {
v = append(v, i)
}
}
参考答案:不会出现死循环,可以正常结束,循环次数在一开始就确定为3次,循环内改变切片的长度,不会影响循环次数,我们可以通过fmt.Println输出看下结果,是正常可以结束的。
观察下列代码,判断输出结果是什么?
func f(n int) (r int) {
defer func() {
r += n
recover()
}()
var f func()
defer f()
f = func() {
r += 2
}
return n + 1
}
func main() {
fmt.Println(f(3))
}
参考答案:输出结果为7,第一步先执行r = n + 1 ,紧接着执行第二个函数,由于此时函数未被定义,抛出异常,执行第一个函数r +=n,异常被recover()捕获,程序正常执行最后return 变量r,程序结束。
range拷贝
观察下列代码,判断输出结果是很么?
func main() {
var a = [5]int{1, 2, 3, 4, 5}
var r [5]int
for i, v := range a {
if i == 0 {
a[1] = 12
a[2] = 13
}
r[i] = v
}
fmt.Println("r = ", r)
fmt.Println("a = ", a)
}
参考答案:r = [1 2 3 4 5] a = [1 12 13 4 5],因为这里循环内是a的副本,无论如何修改原数组a的值,不会改变v的值,因为是进行拷贝后的值,所以想要数组r也有同样的修改效果,需要将代码修改成如下所示:
func main() {
var a = [5]int{1, 2, 3, 4, 5}
var r [5]int
//这里加上指向原数组a的指针
for i, v := range &a {
if i == 0 {
a[1] = 12
a[2] = 13
}
r[i] = v
}
fmt.Println("r = ", r)
fmt.Println("a = ", a)
}
或者将数组a改成切片,因为切片在go的内部结构中有一个指向底层数组的指针,当拷贝的值发生改变时候,副本的指针依旧指向原来的底层数组,所以对切片的修改会同步到底层数组上,所以在通过v获取到的就是修改后的值
func main() {
var a = []int{1, 2, 3, 4, 5} //切片
var r [5]int
for i, v := range a {
if i == 0 {
a[1] = 12
a[2] = 13
}
r[i] = v
}
fmt.Println("r = ", r)
fmt.Println("a = ", a)
}
总结
今天浅谈了Go的习题(十),主要介绍了GO面试中会出现的问题,接下来会继续分享其他的习题的相关知识,对于一个刚入门的我来说,还有许多地方需要学习,有错误的地方欢迎大家指出,共同进步!!,新年快乐,明年继续加油!!!