go语言学习-函数和闭包

来源:互联网 发布:离散最优化算法 编辑:程序博客网 时间:2024/06/04 08:19

1、签名:

go语言中,函数的签名就是函数的参数类型及返回值类型,是这个函数呈现给使用环境的界面,与名字无关。

 

2、函数变量和函数赋值

       go语言支持函数类型的变量和赋值。

相同签名的函数是同一类型的,同一类型的函数才可以相互赋值。

函数变量也是支持强制转换的,不过这里必须是同一类型的函数,才能进行转换。

例:

(1)、强制转换:

packagemain

 

import"fmt"

 

typef_typefunc(x,yint)(int)

 

varff=f_type(func(x,yint)(int){

    fmt.Println("funcff")

    returnx+y

})

 

funcmain(){

    ff(2,4)
}

 

上面代码,首先定义f_type的函数类型,该类型的函数必须有2个int的入参,一个int的出参。然后定义一个两个int入参,一个int出参的匿名函数,并强转成f_type类型赋值给ff。

 

(2)、赋值

packagemain

 

import"fmt"

 

varpr=fmt.Println

varf=func(i,jint)int{

    pr("funcf:")

    pr("i+j=",i+j)

    

    returni+j

}

 

funcmain(){

    pr("tmppr=fmt.Println,anduse\"pr\"toprintinfo")

 

    f(1,3)

}

 

运行结果如下:

F:/go-code/tmp-func/tmp-func.exe[F:/go-code/tmp-func]

tmp pr = fmt.Println, anduse "pr" to print info

func f:

i + j = 4

成功: 进程退出代码 0.

 

3、闭包

       下面内容摘自《Go语言 云动力》,4.5-闭包

 

       和变量的声明不同,Go语言不能在函数里声明另外一个函数。所以在Go的源文件里,函数声明都是出现在最外层的。

       “声明”就是把一种类型的变量和一个名字联系起来。

       Go里有函数类型的变量,这样,虽然不能在一个函数里直接声明另一个函数,但是可以在一个函数中声明一个函数类型的变量,此时的函数称为闭包(closure)。

例:

packagemain
 
import"fmt"
 
funcmain(){
    add:=func(baseint)func(int)(int){
        returnfunc(iint)(int){
            returnbase+i
        }
    }
    
    add5:=add(5)
    fmt.Println("add5(10)=",add5(10))
}

 

       这个例子唯一的使用价值大概就是用来展示闭包的构建和使用。

       add是一个闭包,因为它是无名的函数类型的变量。可以认为它是一个闭包作坊,根据入参返回(生产)一个闭包。这样add5就是使用5作为add的参数得到的一个闭包。

       闭包的声明是在另一个函数的内部,形成嵌套。和块的嵌套一样,内层的变量可以遮盖同名的外层的变量,而且外层变量可以直接在内层使用。如add的base参数在return返回的闭包的外层,所以它的值5在add返回并赋值给add5后依旧存在。当add5执行时,参数i可以从这个外层得到的base相加,得到结果15.

 

       如果联想到函数调用,会奇怪add函数return之后的框架已经不存在了,为什么base还可以用呢?答案是go的编译器会把闭包使用的外围变量分配到堆上,而堆上的变量,是不会随函数返回自动消失的,它们在用完之后,才会被垃圾回收。

 

1 0
原创粉丝点击