函数是撒子?
执行特定任务的代码块
函数的声明
go语言中至少有一个main函数,它是整个程序的入口
语法
func funcName(paremetername type1,paremetername type2)(output1 type1,output2 type2){
//处理逻辑函数
//返回多个值
return v1,v2
}
可变参
go语言函数支持变参,接收变参的函数是有着不定数量的参数的,为了做到这点,首先需要定义函数使其接收变参:
function funcName(argName ...int){ //此处的int可以是其他任意的数据类型
//
}
arg ...int告诉go这个函数接收不定数量的参数,对于函数体来说,可变参数相当于一个切片,可以使用for循环遍历得到全部参数,调用函数的时候,可以传入0-多个参数。
注意:一个函数的参数列表最多只能有一个可变参数,当存在可变参数时,可变参数在放在参数列表的最后,如:func function(name,sex string,score ...int){//}
在调用某个使用可变参数的函数时,若想将一个切片作为参数传入,则在实参切片名后加上三个点...
函数的返回值:
若主程序需要使用到函数内的变量,则需要将函数中的变量通过返回值返回,有返回值时需要在声明函数时参数列表的后面加上返回值列表,声明要返回的变量以及数据类型。
在返回值列表中,可以不声明具体的变量名,只声明返回值的数据类型,在函数体最后return具体的变量或数值即可。
当返回值只有一个,又省略了返回值变量时,返回值列表的括号也可以省略,直接写上返回值的类型即可。
例子:
func getSum1(num ...int)int{
sum := 0
//
return sum
}
func getSum2(num ...int)(sum int){
for _,v := range num{
sum +=v
}
return sum
}
空白表示符 _
_是go语言中的空白标识符,他可以代替任何类型的任何值。专门用来舍弃数据
func function()(a int ,b float64){
return _,52.52
}
函数的本质
函数实质上也是一个特殊的变量,它存储的是函数体所在的地址(即指向了函数体)。
函数的类型描述为 :func (参数类型列表)(返回值类型列表),如func (int int)(int float64)
因此,当有一个函数的声明为 func myfunc (name string,age int)int {//}时,它的函数类型即为func(string,int)int,此时你可以创建一个变量a,类型为func(string,int)int,并将myfunc赋值给a,这时你可以使用a来调用函数myfunc
func function(num int, name string) int {
  fmt.Println(num, name)
  return 0
}
func main() {
  fmt.Println("HelloWorld!")
  var a func(int, string) int
  a = function
  fmt.Println(a)
  fmt.Println(function)
  a(10086, "hello")
} 
 
匿名函数
即没有名字的函数,通常只能调用一次,当然你也可以定义一个变量来保存匿名函数,这样就可以多次调用该函数了。
    func() {
      fmt.Println("这是一个匿名函数")
    }()//注意此处要带上括号,表示这个匿名函数被调用了,不然就是报错的
    var a = func(num1, num2 int) {//带参数的匿名函数
        fmt.Println("这是一个赋值给变量的匿名函数")
        fmt.Println(num1 + num2)
    }
    a(100, 200)
    a(300, 400) 
匿名函数的作用
1.将匿名函数作为另一个函数的参数
接收一个函数作为参数的函数叫做高阶函数,而作为参数的函数则称之为回调函数
//例子:设计一个函数用来求两个整数的加减乘除运算
func oper(a,b int,fun func(int,int)int)int{
    res  := fun(a,b)
    return res
}
//调用时:
ex := oper(100,200,func(a,b int)int{
    return a + b
})
fmt.Println(ex) 
 
2.将匿名函数作为另一个函数的返回值,可以形成闭包结构
一个外层函数中,有内层函数,该内层函数中,会操作外层函数的局部变量(不管是外层函数收到的参数还是外层函数中定义的局部变量),并且该外层函数的返回值就是这个内层函数,这个内层函数和外层函数的局部变量,统称为闭包结构
局部变量的生命周期会发生改变,正常的局部变量随着函数调用而创建,随着函数的结束而销毁。但是闭包结构中的外层函数的局部变量并不会随着外层函数的结束而销毁,因为内层函数还要继续使用
例子:
func outfunc() func() int {
  i := 0
  infunc := func() int {
    i++
    return i
  }
  return infunc
}
func main() {
  res := outfunc()
  fmt.Println(res())//1
  fmt.Println(res())//2  
  //因为内层函数作为返回值返回了,所以外层函数中的局部变量并没有被销毁
  res2 := outfunc()
  fmt.Println(res2())//1
  fmt.Println(res2())//2
  //res和res2指向的是同一个内层函数的地址,调用的是同一块代码
  //但他们两个操作的变量i是不同的
}









