Golang的学习笔记(10)--Go函数

目录

Go函数

    函数是基本的代码块,它的作用是可以将实现某个功能的多行代码封装到一段代码块中(即函数),在需要的时候去调用。同个函数可以被多次调用,实现代码重用。
     函数一般会有参数和返回值(也可以没有),函数名称、函数参数、函数返回值以及它们的类型被统称为函数签名
     在Go语言中,函数有以下一些特点:

  • 支持不定长变参、多返回值、命名返回值参数
  • 支持匿名函数、闭包
  • 函数可以作为一种类型使用
  • Go函数不支持嵌套、重载

Go函数定义

    Go函数定义格式如下:

func function_name ([parameter list]) [return_type]{
   函数体
}
funcparameter listparam1 type1, param2 type2...return_typeret1 type1

函数值传递与引用传递

    Go函数被调用的时候,传入的参数会被复制然后传递到函数内部使用,即函数体中使用的是参数副本。这种方式也称之为值传递

&slicemap

Go函数的各种使用形式

return
func main(){
   r1, r2 := A(1, "A")
}
func A(a int, b string) (int, string) {
   c := a + 1
   d := b + "aa"
   return c, d
}
  • 多个参数如果类型相同,可以合并写法,单个返回值可以不写括号
func main(){
   r3 := B(1, 2, 3)
}
func B(a, b, c int) int {
   return a + b + c
}
return
func main(){
   r4, r5, r6 := C()
}
func C() (a, b, c int) {
   a, b, c = 1, 2, 3
   return
}
...typeslice
func main(){
   r7 := D(0,1,2,3)
}
func D(base int , s ...int) int {
   for _, v := range s {
      base += v
   }
}
slicesliceslice
  • 传递指针参数(引用传递)
func main(){
   p := 1
   G(&p)
   fmt.Println(p)
}
func G(p *int) {
   *p = 2
   fmt.Println(*p)
}
  • 传递引用类型参数(引用传递)
func main(){
   s := []int{1, 2, 3, 4}
   F(s)
   fmt.Println(s)
}
func F(s []int) {
   s[0] = 5
   s[1] = 6
   s[2] = 7
   s[3] = 8
   fmt.Println(s)
}
  • 函数作为一种类型来使用
func main(){
    h := H
    h()
}
func H() {
   fmt.Println("H")
}
  • 将函数调用的结果作为其它该函数的参数。只要只要这个被调用函数的返回值个数、返回值类型和返回值的顺序与调用函数所需求的实参是一致的
func main(){
   r := f1(f2(5))
}
func f1(a,b,c int) int {
   return a+b+c
}
func f2(a int) (b,c,d int){
   b = a
   c = a + 1
   d = a - 1
   return
}
  • 将函数作为一种参数类型,即函数可以作为其它函数的参数进行传递,然后在其它函数内调用执行,一般称之为回调。注意和上一点进行区分
type cb func(int) int

func main() {
    testCallBack(1, callBack)
    testCallBack(2, func(x int) int {
        fmt.Printf("我是回调,x:%d\n", x)
        return x
    })
}
func testCallBack(x int, f cb) {
    f(x)
}
func callBack(x int) int {
    fmt.Printf("我是回调,x:%d\n", x)
    return x
}

匿名函数

    匿名函数,顾名思义即没有名字的函数。匿名函数不能独立地定义,它需要赋值给某个变量,即保存函数的地址到变量中,然后通过变量对函数进行调用。或者定义的同时直接调用

func main(){
   i := func(){
   fmt.Println("匿名函数赋值给变量再调用")
 }
   i()
   func(){
     fmt.Println("匿名函数直接调用")
   }()
}

     Go的匿名函数支持闭包。关于闭包的概念:

闭包函数:声明在一个函数中的函数,叫做闭包函数
闭包:闭包函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回之后
closurex1112
func main(){
    f := closure(10)
    fmt.Println(f(1))
    fmt.Println(f(2))
}
func closure(x int) func(int) int {
   return func(y int) int {
     return x + y
   }
}

defer 函数

deferdefer
deferdeferdeferdefer
func main(){
   for i := 0; i < 3; i++ {
     defer fmt.Println(i)          //将逆序输出  2  1  0
   }
}
defertry-catchpanic-recover
panicrecoverdeferrecoverdeferpanic
func main(){
   beforePanic()
   panicRecover()
   afterPanic()
}
func beforePanic() {
   fmt.Println("before panic")
}
//panic-recover
func panicRecover() {
   defer func() {
     if err := recover(); err != nil {
       fmt.Println("Recover in this")
     }
   }()
   panic("Panic !!!")
}
func afterPanic() {
   fmt.Println("after panic")
}