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的编译器会把闭包使用的外围变量分配到堆上,而堆上的变量,是不会随函数返回自动消失的,它们在用完之后,才会被垃圾回收。
有疑问加站长微信联系(非本文作者)