Go - 函数

定义

语法 - func 函数名 (参数列表) (返回值列表){

}

package main

import (
    "fmt"
)

func myfunc(a, b int) (r1, r2 int) {
    r1 = a + b
    r2 = a - b
    return
}

func main() {
    r1, r2 := myfunc(5, 1)
    fmt.Println(r1)
    fmt.Println(r2)
}

//output
6
4

 

匿名函数

Go  语言允许将函数传递给一个变量,即定义函数也算是定义一种类型。 声明匿名函数时,可以省略函数的名称

func main() {
    f1 := func() {
         fmt.Println("I am fuction 1...")
    }
    f1()
}

//output
I am fuction 1...

 

闭包

func closure(x int) func(y int) (r int) {
    fmt.Printf("%p\n", &x)
    return func(y int) (r int) {
        fmt.Printf("%p\n", &x)
        r = x + y
        return r
    }
}

func main() {
    
    f2 := closure(10)
    fmt.Println(f2(1))
    fmt.Println(f2(2))

}

//output
0x114821dc
0x114821dc
11
0x114821dc
12

 

defer

Go 函数通过使用defer关键字,实现了许多“神奇”的事情

1. 改变函数执行的顺序 - 如果在函数体中定义 defer, 会按照与定义顺序相反的顺序执行

func main() {
    
    for i := 0; i < 3; i++ {
        defer fmt.Println(i)
    }

}

//output
2
1
0

 

2. Go语言没有异常处理(try...catch),但可以使用 “panic + recover” 模式来处理异常. panic可以在任何地方触发,但是recover必须在defer调用的函数中执行,且必须定义在panic之前

func A() {
    fmt.Println("function A ...")
}

func B() {
    defer func() {
        if err := recover(); err != nil {
            fmt.Println("recover")
        }
    }()
    panic("panic in function B")
}

func C() {
    fmt.Println("function C ...")
}

func main() {
    
    A()
    B()
    C()

}

//output
function A ...
recover
function C ...

所以: 通过使用defer + recover 的方式,可以达到 “finally”的效果,例如清理资源,关闭文件等。

 

posted @ 2017-05-14 22:50  TonyZhang24  阅读(174)  评论(0编辑  收藏  举报