「这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战」。
Go语言学习查缺补漏ing Day10
本文收录于我的专栏:《让我们一起Golang》
零、前言
因为笔者基础不牢,在使用Go语言的时候经常遇到很多摸不着头脑的问题,所以笔者下定决心好好对Go语言进行查漏补缺,本【Go语言查缺补漏ing】系列主要是帮助新手Gopher更好的了解Go语言的易错点、重难点。希望各位看官能够喜欢,点点赞、关注一下呗!
一、for range 使用:=的形式迭代变量时出现的一个问题
看下面这段代码,思考输出结果是什么?为什么?
1 | go复制代码package main |
我们想要获得的结果应该是:
1 | go复制代码{A} {B} {C} |
但是,实际上是这样的吗?来看一下输出结果:
1 | go复制代码{A} {B} {C} |
为什么会出现这种情况?
因为当我们在for range循环中使用:=的形式迭代变量时,索引index以及值value会在每次循环都会被重用,而不是新开辟一块新的内存空间存放。所以这里slice2每一次放入的都是值value的地址,所以最后一次循环时,value是{C},而因为前面存入的地址都是value的地址,故存入的都是{C}。
有什么解决办法?
第一个解决办法自然是不存储指针,而是存值:
1 | go复制代码package main |
1 | go复制代码{A} {B} {C} |
这样虽然还是重用,但是每次value的值都被保存了,保存的不是指针,因此最后输出结果没问题。但是这个貌似输出结果不是我们想要的那样。
那么还有没有其它办法呢?
1 | go复制代码package main |
我们可以这样,虽然value的地址是固定的,但是slice1[index]的地址是不一样的。我们可以取slice1的地址。
这样的输出结果是:
1 | go复制代码{A} {B} {C} |
二、多重赋值需要掌握的易错点
看下面这段代码,请问输出结果是什么?
1 | go复制代码package main |
答案是:
1 | go复制代码s: [A Z C D] |
为什么呢?
其实我们的多重赋值是按步骤进行的,不是同时进行,而是有前后顺序:
第一个阶段是估值阶段,然后是实施阶段:
比如:
1 | go复制代码a, b = b, a |
下面是估值阶段:
1 | go复制代码// 估值阶段 |
然后是实施阶段:
1 | go复制代码// 最基本形式:*P0, *P1 = R0, R1 |
实施阶段中的赋值操作并不会对估值阶段的结果造成影响。
而且,我们这里先计算=左边的索引表达式或取址表达式,然后计算=右边的表达式。再之后就是进行赋值操作。
所以我们这里先计算索引表达式i+1,然后进行赋值运算。
本文转载自: 掘金