每次学习并整理一个Golang的知识点,每天进步一点点。今天巩固下19问中提到的知识点:defer与返回值🤔

日省吾身

  1. 写出下面代码片段的输出结果?
 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的过程可以拆分成以下几步:

  1. 将返回值result赋值给一个新的返回值nValue,nValue := result(可以理解成自动创建了一个新的返回值nValue)
  2. 然后检查是否有defer函数,如果有则执行
  3. 返回刚才创建的返回值: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. 下列代码片段示例,语法错误的有?
 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_qrcode_gh