每次学习并整理一个Golang的知识点,每天进步一点点。今天巩固下19问中提到的知识点:defer与返回值🤔
日省吾身
- 写出下面代码片段的输出结果?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
func f1() (result int) {
defer func() {
result++
}()
return 0
}
func f2() (result int) {
t := 5
defer func() {
t = t + 5
}()
return t
}
func f3() (r int) {
defer func(r int) {
r = r + 5
}(r)
return 2
}
func main() {
fmt.Println(f1())
fmt.Println(f2())
fmt.Println(f3())
}
|
思考后看下方答案…
答疑解惑
参考答案:
1. 程序输出结果为:1 5 2
在19问中,我们提到过defer在匿名返回值和具名返回值函数中的不同表现;发现还是有同学没有完全理解,这里虽然都是具名函数,但也可以套用公式,下面我们再写一下拆解的公式,并逐一进行拆解分析;
如果是匿名返回值函数,最后return的过程可以拆分成以下几步:
- 将返回值result赋值给一个新的返回值nValue,nValue := result(可以理解成自动创建了一个新的返回值nValue)
- 然后检查是否有defer函数,如果有则执行
- 返回刚才创建的返回值:nValue
如果是具名返回值函数,由于返回值在方法定义时已经被定义,所以不需要执行上述第1步的赋值过程,执行2和3两步;下面我们参照公式对上述题目做下拆解:
f1():
1
2
3
4
5
6
|
func f1() (result int) {
defer func() {
result++
}()
return 0
}
|
f1()拆解后::
1
2
3
4
5
6
7
|
func f1New() (result int) {
result = 0 // 具名函数返回值result变量在函数创建时已被定义且赋值为0
defer func() { // defer里有匿名函数调用,这里值传递相当于拷贝的是函数指针,result的值被修改为1
result++
}()
return result // 返回result的值,1
}
|
f2():
1
2
3
4
5
6
7
|
func f2() (result int) {
t := 5
defer func() {
t = t + 5
}()
return t
}
|
f2()拆解后::
1
2
3
4
5
6
7
8
|
func f2New() (result int) {
t := 5
result = t // 具名函数返回值result变量在函数创建时已被定义且赋值为5
defer func() {
t = t + 5 // 不涉及返回值result的修改
}()
return result // result的值还是为最开始的赋值5
}
|
f3():
1
2
3
4
5
6
|
func f3() (r int) {
defer func(r int) {
r = r + 5
}(r)
return 2
}
|
f3()拆解后::
1
2
3
4
5
6
7
|
func f3New() (r int) {
r = 2 // 具名函数返回值r变量在函数创建时已被定义且赋值为2
defer func(r int) {
r = r + 5 // defer里有匿名函数调用,但是这里的r为值传递,相当于修改的是r的副本,真正的返回值r并未被修改
}(r)
return r // r的值还是最开始的赋值,2
}
|
以上,你做对了吗?😊
其他相关答案或补充知识点,欢迎在评论区留言补充!
下期提问
- 下列代码片段示例,语法错误的有?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// P 结构体
type P struct {
}
func f1(i interface{}) {
}
func f2(i *interface{}) {
}
func main() {
m := P{}
n := &s
f1(m) //A
f2(m) //B
f1(n) //C
f2(n) //D
}
|
答案及解析将在下期文章中给出,欢迎大家在评论区写出你的答案;独乐乐不如众乐乐,欢迎交流学习,互相进步。
欢迎转发和评论。更多优质原创文章,欢迎关注微信公众号“IYue爱月”或扫描下方二维码:
文章作者
xujpxm
上次更新
2020-10-15
许可协议
CC BY-NC-ND 4.0 非商业转载请注明出处(作者,原文链接),商业转载请联系作者授权,谢谢!