递归求1~100的和

func fn1(a int) int{
if a>1{
return a+fn1(a-1)
}else{
return 1
}
}

函数闭包

全局变量特点:

  • 1.常驻内存
  • 2.污染内存

局部变量特点:

  • 1.不常驻内存
  • 2.不污染内存

闭包:

  • 1.可以让一个变量常驻内存
  • 2.可以让一个变量不污染全局

闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式就是在一个函数里创建另一个函数,通过另一个函数去访问
闭包过多影响程序性能

func fn2() func() int{
var a=10
return func fn2_1() int{
a=a+1
return a
}
}

然后我们在主函数内调用

a:=fn2()
fmt.Println(a())
fmt.Println(a())
fmt.Println(a())

第一个打印结果便是11,那后面两个呢?结合闭包所说可以让一个便变量常驻内存便可以猜到结果是12,13

defer延后执行

这个便是今天学的最难理解的知识,首先还是先看看几个简单的列子先

ex1

defer fmt.Println("开始")
defer fmt.Println("结束")

结果是 结束,开始
这里很简单,理解为先defer的后执行,后defer的先执行

ex2

defer fmt.Println("开始")
fmt.Println("1")
fmt.Println("2")
defer fmt.Println("3")
defer fmt.Println("结束")

结合上面所说结果便是
1,2,结束,3,开始

ex3

这里开始难度就有点上升了
比如我在主函数数定义了一个

func test1() int{
a:=5
defer func(){
a=a+1
}()
return a
}

这里的返回值便是5
理解我我们先将a赋值给返回值,再执行defer a=a+1,a的值虽然变了,但我们已经返回值赋过值了,然后return 返回值
return——defer:1.返回值=x,运行defer,ret指令

ex4

func test2(){
fmt.Println("开始")
defer func(){
fmt.Println("111")
}()
fmt.Println("结束")
}

结果很明显是开始,结束,111

ex5

我们将ex3稍微改造一下

func test1() (a int){
a:=5
defer func(){
a=a+1
}()
return
}

在这里我指定了返回值为a,那么结果会发生变化吗?答案是肯定要变化的,正如上面所说我们先将给返回值赋值,但此时返回值就是a,
a=a+1,那么最后返回的值就是6

ex6

我们再改造以下ex6

func test1() (a int){
a:=5
defer func(a int){
a=a+1
}()
return
}

这里返回的是5,ex6与ex5的区别在于我在自治函数里指定了参数a,这样就有了两个a,我理解的是他们的地址不同我们最终需要的是第一个a

ex7

package main

import (
"fmt"
)

func hello(i *int) int {
defer func() {
*i = 19
}()
return *i
}

func main() {
i := 10
j := hello(&i)
fmt.Println(i, j)
}

这里的结果是19,10
调用hello函数时我们传入了i的地址,由于defer,我们先执行将i地址的变量的值赋值给了j,然后再再讲i所在地址的变量的值改为了19

ex8

package main

import "fmt"

func calc(index string, a, b int) int {
fmt.Println(index, a, b, a+b)
return a + b
}

func main() {
x := 1
y := 2
defer calc("AA", x, calc("A", x, y))
x = 10
defer calc("BB", x, calc("B", x, y))
y = 20
}

defer 注册要延迟执行的函数时该函数所有的参数都需要确定其值,有了这句话我们便可以理解该题

我们首先按顺序执行到第一个defer

defer calc(“AA”, x, calc(“A”, x, y))

正如上面所说我们所有的参数要确定其值,所以肯定要执行

calc(“A”, x, y)

此时便打印出:A 1 2 3 。然后返回3

这样就变为了defer calc(“AA”,1,3)

然后其参数值都确定以后按照先defer的后执行

然后接着此时x的值变为了10

我们接着按顺序到了第二个defer

defer calc(“BB”, x, calc(“B”, x, y))

同样的我们要先确定其值

calc(“B”, x, y)

此时便打印出:A 10 2 12 。然后返回12

这样就变为了defer calc(“BB”,10,12)

紧接着y的值虽然变化了,但我们前面的值都已经确定了。

然后其参数值都确定以后按照先defer的后执行,后defer的先执行

所以最终的结果是

  • A 1 2 3
  • B 10 2 12
  • BB 10 12 22
  • AA 1 3 4

总结

这里的面试题居多要好好的理解