函数

Go语言中支持函数、匿名函数和闭包

函数的定义:

func 函数名(参数)(返回值){
    函数体
}
参数和返回值是可选项,可以没有

函数作为参数传入另一个函数:

func f1()  int {
	return 10
}

func f2(x func() int) int{
	ret := x()
	//fmt.Println(ret)
	return 100 +ret
}

 如果局部变量和全局变量重名,优先访问局部变量。

//定义全局变量num
var num int64 = 10

func testNum() {
	num := 100
	fmt.Printf("num=%d\n", num) // 函数中优先使用局部变量
}
func main() {
	testNum() // num=100
}

匿名函数

func main() {
	//匿名函数就是没有名字的函数,在函数内使用,因为函数内不能有带名字的函数
	temp := func(x,y int) {
		fmt.Println(x+y)
	}
	temp(1,6)
	//立即执行函数,只执行一次的情况
	func(x,y int){
		fmt.Println(x+y)
		fmt.Println("hello")
	}(10,34)
}

闭包

package main

import "fmt"

func f11(f func())  {
    fmt.Println("this is f11")
    f()
}
func f22(x,y int)  {
    fmt.Println("this is f22")
    fmt.Println(x+y)
}
//需求,运行f11(f22)
//实际可能的背景,f11调用f22,但是并不能直接调用,用闭包的方式来解决
//同步模块,会用到闭包功能
//需求拆解:f11的输入是一个函数,所以f33的输出就是f11的输入,f33的输入可以做成传函数的方式,把f22传进去
//总结:f33运行f22里的东西返回一个函数,然后f11来调用
func f33(f func(int,int),x,y int) func()  {
    //ret := func() {
    //    fmt.Println("this is f22")
    //    fmt.Println(x+y)
    //}
    //return ret
    ret := func() {
        f(x,y)
    }
    return ret

}
//闭包 = 函数 + 引用参数
func main() {
    //实现了f11不需要传参数的目的
    temp := f33(f22,6,7)
    f11(temp)
    //单纯的f33(f22,6,7) 不会有输出,因为f33只是返回一个函数,不会运行。包括里面的ret也没有运行
}

 defer机制

package main

import "fmt"
//由于defer语句延迟调用的特性,所以defer语句能非常方便的处理资源释放问题。
//比如:资源清理、文件关闭、解锁及记录时间等。
func aa()  {
	fmt.Println("begin")
	//可以把最后执行的放在一个自运行函数里面
	defer func (){
		fmt.Println(111)
		fmt.Println(222)
	}()
	fmt.Println("end")
}
func main() {
	//多个defer逆序执行,最先定义的最后执行
	// 先被defer的语句最后被执行,最后被defer的语句,最先被执行。
	defer fmt.Println(10)
	defer fmt.Println(20)
	aa()
}

panic与recover

package main

import (
    "errors"
    "fmt"
)

//模拟读取文件的例子
func readFilname(filename string) error{
    if filename =="main.go"{
        return nil
    }else{
        return errors.New("读取文件错误.....")
    }
}

func myReadFile()  {
    //如果触发panic。就要用recover捕获
    defer func() {
        ret := recover()
        if ret!=nil{
            fmt.Println("给管理员发送邮件:",ret)
        }
    }()
    err := readFilname("xxx.go")
    if err !=nil{
        panic(err)
    }
}
func main() {
    myReadFile()
    fmt.Println("继续执行。。")
    //recover()必须搭配defer使用。
    //defer一定要在可能引发panic的语句之前定义。
}

 

posted @ 2023-03-19 18:49  hjtt  阅读(35)  评论(0)    收藏  举报