函数
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的语句之前定义。 }

浙公网安备 33010602011771号