1.匿名函数与闭包
1.1匿名函数
前面我们定义函数的时候,发现是不能在一个函数中,再次定义一个函数。如果我们想在一个函数中再定义一个函数,那么可以使用匿名函数,所谓匿名函数就是没有名字的函数。
如下所示:
package main
import "fmt"
func main() {
var num int
num=9
f:=func(){
num++
fmt.Println(num)
}
f()
fmt.Println(num)
}
在main( )函数中定义了一个匿名函数,定义的方式非常简单func(){ 函数体 }, 一定要注意的是在func的后面没有函数的名字,同时在这里定义的该匿名函数也没有参数。我们将定义好的匿名函数赋值给了变量f,那么变量f就是一个函数类型。要想执行该匿名函数,就可以通过f( )的方式去调用执行。
在这里,有一件非常有意思的事情,就是在匿名函数中可以直接访问main( )函数中定义的局部变量,并且在匿名函数中对变量的值进行了修改,最终会影响到整个main( )函数中定义的变量的值。
ackage main
import "fmt"
func main() {
var num int
num=9
f:=func(){
num++
fmt.Println("匿名函数",num)
}
type functype func()
var f1 functype
f1=f
f1()
fmt.Println("main函数",num)
}
上面案例中,定义的匿名函数赋值给了变量f,那么f的类型就是函数类型,所以我们自己也可以定义一个函数类型的变量来调用匿名函数。但是上面的应用比较繁琐,实际用的比较少。
下面看一下怎样给匿名函数传递参数,并且匿名函数如果有返回值,并接收处理:
package main
import "fmt"
func main() {
x,y:=func(i,j int)(max,min int){
if i>j{
max=i
min=j
}else{
max=j
min=i
}
return
}(30,59)
fmt.Println(x,y)
}
以上案例中定义了一个匿名函数,该匿名函数需要两个整型参数,同时指定了该函数返回值的名字是变量max与min
当执行到return时,让变量manx与min返回,赋值了变量x,y。x中存储的是max变量的值,y中存储的是min变量的值。
以上就是关于什么是匿名函数,以及匿名函数的使用。匿名函数最主要的功能就是实现了闭包。
1.2闭包
所谓的闭包是指有权访问另一个函数作用域中的变量的函数,就是在一个函数内部创建另一个函数。
在Go语言里,所有的匿名函数(Go语言规范中称之为函数字面量)都是闭包。
根据以上定义,那么上一节定义的匿名函数其实就是闭包。(仔细体会上一节定义的匿名函数)
(也可以这样理解闭包:虽然不能在一个函数里直接声明另一个函数,但是可以在一个函数中声明一个函数类型的变量,此时的函数称为闭包(closure))
下面我们通过一个案例,看一下关于闭包的应用。
思考:以下程序执行的结果是:
package main
import "fmt"
func test() int {
var x int
x++
return x
}
func main() {
fmt.Println(test())
fmt.Println(test())
fmt.Println(test())
}
虽然Test( )函数调用了三次,但是输出都是1.原因是:
每次调用Test( )函数,都是重新声明变量x,当函数执行完成后,x会自动被释放所占资源。
如果想实现累加运算,这里就需要用到闭包(匿名函数)。
package main
import "fmt"
func test() func()int{
var x int
return func()int{
x++
return x
}
}
func main() {
f:=test()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
}
由于在定义Test( )函数时指定了返回的类型是一个匿名函数,并且该匿名函数返回的类型是整型。
所以在Test( )函数中定义了一个匿名函数,并且将整个匿名函数返回,匿名函数返回的是整型。
在main( )函数中定义了一个变量f,该变量的类型是匿名函数,f( )表示调用执行匿名函数。
最终执行完成后发现,实现了数字的累加。
因为匿名函数(闭包),有一个很重要的特点:
它不关心这些捕获了的变量和常量是否已经超出了作用域,所以只有闭包还在使用它,这些变量就还会存在。
2.递归函数
如果一个函数在内部不调用其它的函数,而是自己本身的话,这个函数就是递归函数。
例如:
package main
import "fmt"
func test(a int) {
if a==1{
fmt.Println("a=",a)
return
}
test(a-1)
fmt.Println("a1=",a)
}
func main() {
test(3)
}
举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * … * n