go-day2

函数

函数的定义

基本格式

func f1() {
    fmt.Println("Hello!")
}

参数的格式

有参数的函数

func f2(name string) {
    fmt.Println("Hello", name)
}

参数类型简写

// 参数类型简写
func f4(x, y int) int {
    return x + y
}

可变参数

// 可变参数
func f5(title string, y ...int) int {
    fmt.Println(y) // y是一个int类型的切片
    return 1
}

返回值的格式

有返回值

// 带参数和返回值的函数
func f3(x int, y int) int {
    sum := x + y
    return sum
}

多返回值

// Go语言中支持多个返回值
func f7(x, y int) (sum int, sub int) {
    sum = x + y
    sub = x - y
    return
}

命名返回值

// 命名返回值
func f6(x, y int) (sum int) {
    sum = x + y // 如果使用命名的返回值,那么在函数中可以直接使用返回值变量
    return      // 如果使用命名的返回值,return后面可以省略返回值变量
}

变量作用域

  1. 全局作用域
  2. 函数作用域
    1. 先在函数内部找变量,找不到往外层找
    2. 函数内部的变量,外部是访问不到的
  3. 代码块作用域
var x = 100 // 定义一个全局变量

// 定义一个函数
func f1() {
    // x := 10
    name := "a"
    // 函数中查找变量的顺序
    // 1\. 先在函数内部查找
    // 2\. 找不到就往函数的外面查找,一直找到全局
    fmt.Println(x, name)
}

func main() {
    f1()
    // fmt.Println(name) // 函数内部定义的变脸只能在该函数内部使用

    // 语句块作用域
    if i := 10; i < 18 {
        fmt.Println("上学")
    }
    // fmt.Println(i) // 不存在i
    for j := 0; j < 5; j++ {
        fmt.Println(j)
    }
    // fmt.Println(j) // 不存在j
}

高阶函数

函数也是一种类型,它可以作为参数,也可以作为返回值。

// 函数也可以作为参数的类型
func f3(x func() int) {
    ret := x()
    fmt.Println(ret)
}

func ff(a, b int) int {
    return a + b
}

// 函数还可以作为返回值
func f5(x func() int) func(int, int) int {
    return ff
}

匿名函数

没有名字的函数。

多用在函数内部定义函数时使用。

func main() {

    // 函数内部没有办法声明带名字的函数
    // 匿名函数
    f1 := func(x, y int) {
        fmt.Println(x + y)
    }
    f1(10, 20)

    // 如果只是调用一次的函数,还可以简写成立即执行函数
    func(x, y int) {
        fmt.Println(x + y)
        fmt.Println("Hello world!")
    }(100, 200)
}

闭包

1563005182920.png

defer

defer延迟调用,会把defer后面的语句延迟调用

把当时的状态都保存

defer多用于释放资源

多个defer存在时,按照先进后出的方式去执行。

func calc(index string, a, b int) int {
    ret := a + b
    fmt.Println(index, a, b, ret)
    return ret
}

func main() {
    a := 1
    b := 2
    defer calc("1", a, calc("10", a, b))
    a = 0
    defer calc("2", a, calc("20", a, b))
    b = 1
}

// 1\. a:=1
// 2\. b:=2
// 3\. defer calc("1", 1, calc("10", 1, 2))
// 4\. calc("10", 1, 2) // "10" 1 2 3
// 5\. defer calc("1", 1, 3)
// 6\. a = 0
// 7\. defer calc("2", 0, calc("20", 0, 2))
// 8\. calc("20", 0, 2) // "20" 0 2 2
// 9\. defer calc("2", 0, 2)
// 10\. b = 1
// calc("2", 0, 2) // "2" 0 2 2
// calc("1", 1, 3) // "1" 1 3 4

// 最终的答案:
// "10" 1 2 3
// "20" 0 2 2
//  "2" 0 2 2
// "1" 0 3 3

内置函数

1563014612689.png

panic和recover

func funcA() {
    fmt.Println("a")
}

func funcB() {
    // 刚刚打开数据库连接
    defer func() {
        err := recover()
        fmt.Println(err)
        fmt.Println("释放数据库连接...")
    }()
    panic("出现了严重的错误!!!") // 程序崩溃退出
    fmt.Println("b")
}

func funcC() {
    fmt.Println("c")
}
func main() {
    funcA()
    funcB()
    funcC()
}

你可能感兴趣的:(go-day2)