//函数声明的格式
func funcName(in1 type1,in2 type2...) (out1 type1,out2 type2...){
return value1,value2...
}
func add(a,b int)int{
return a+b
}
type addFunc func(a,b int)int
这段代码的意思是,长这样的函数func(a,b int)int属于addFunc类型,既然有了类型,那么就可以定义这样类型的变量。
type addNum func(int,int)int
func main(){
var a addNum=add
b:=add
fmt.Println(a(1,3))
fmt.Println(b(5,7))
}
func add(a,b int)int{
return a+b
}
go语言中函数也是值(first-class value)可以赋值给变量
但是,如果现在还有一个函数f。
func f(s string,x,y int) string{
fmt.Sprintf(s,"%d %d",x,y)
return s
}
那么,显然f不能赋值给a(类型不一样),f也不能赋值给b,因为b的类型也确定了,和f不一样。
既然函数可以作为类型,那么我们就可以把这个类型的函数当成值来进行传递。
type FormatFunc func(s string,x,y int) string
func main(){
b:=format(func(s string,x,y int)string{
return fmt.Sprintf(s,x,y)
},"%d%d",1,2)
fmt.Println(b)
}
func format(ff FormatFunc,s string,x,y int) string{
return ff(s,x,y)
}
如果一个函数的最后一个参数是…type的形式那么这里函数可以处理类型为type的变长参数。
func minAndmax(s string ,a...int)int{
if len(a)==0{
return -1
}
if s=="max"{
max:=a[0]
for _,v:=range a{
if v>max{
max=v
}
}
return max
}else if s=="min"{
min:=a[0]
for _,v:=range a{
if v<min{
min=v
}
}
return min
}else{
return -1
}
}
传递参数的方法有两种,一种是手动填写参数,一种是将这堆数据存在数组arr中,通过arr…传递。
//手动填写参数
age:=minAndmax("min",9,3,1,5,2)
fmt.Printf("最小的年龄为%d\n",age)
//数组作为参数
arr:=[]int{2,4,1,5,6,3}
age=minAndmax("max",arr...)
fmt.Printf("最大的年龄为%d\n",age)
匿名函数是在函数声明时没有名字的一种函数,不能独立存在。
func(num int){
sum:=0
for i:=0;i<=num;i++{
sum+=i
}
fmt.Println(sum)
}
闭包函数赋值
a:=func(num int){
sum:=0
for i:=0;i<=num;i++{
sum+=i
}
fmt.Println(sum)
}
闭包函数调用
在函数体后面加上括号,如果有参数就传入参数。
func(num int){
sum:=0
for i:=0;i<=num;i++{
sum+=i
}
fmt.Println(sum)
}(100)
func main(){
j:=5
a:=func() func(){
i:= 10
return func() {
fmt.Printf("i=%d j=%d\n",i,j)
}
}()
a()
}
由闭包函数继承了声明时的作用域可知,这个闭包访问在声明前的变量j是合法的。
func main(){
func1:=ins()
fmt.Println(func1())
fmt.Println(func1())
fmt.Println(func1())
func2:=ins()
fmt.Println(func2())
fmt.Println(func2())
}
func ins() func() int{
i:=0
return func() int{
i++
return i
}
}