Go语言函数高级篇
创始人
2024-05-28 23:30:36
0

Go语言函数高级篇

  • 1.高阶函数
    • 函数作为参数
    • 函数作为返回值
  • 2.匿名函数
  • 3.defer
  • 4.内置函数

1.高阶函数

高阶函数分为函数作为参数和函数作为返回值两部分。

函数作为参数

函数可以作为参数:

package mainimport "fmt"func add(x, y int) int {return x + y
}func mul(x, y int) int {return x * y
}func calc(x, y int, op func(int, int) int) int {return op(x, y)
}func main() {res := calc(10, 20, add)fmt.Println(res)  // 30resP := calc(10, 20, mul)fmt.Println(resP)  // 200
}

函数作为返回值

函数也可以作为返回值:

package mainimport ("errors""fmt"
)func add(x, y int) int {return x + y
}func mul(x, y int) int {return x * y
}func do(s string) (func(int, int) int, error) {switch s {case "+":return add, nilcase "*":return mul, nildefault:return nil, errors.New("无法识别")}
}func main() {f, err := do("+")fmt.Println(err, f(10, 20)) //  30f2, err2 := do("-")fmt.Println(f2, err2)  //  无法识别
}

2.匿名函数

函数当然还可以作为返回值,但是在Go语言中函数内部不能再像之前那样定义函数了,只能定义匿名函数。匿名函数就是没有函数名的函数,匿名函数的定义格式如下:

func(参数)(返回值){函数体
}

匿名函数因为没有函数名,所以没办法像普通函数那样调用,所以匿名函数需要保存到某个变量或者作为立即执行函数:

package mainimport "fmt"func main() {// 将匿名函数保存到变量add := func(x, y int) {fmt.Println(x + y)}// 调用匿名函数add(10, 20) // 30// 自执行函数:匿名函数定义完加()直接执行func(x, y int) {fmt.Println(x + y)}(20, 20)  // 40
}

3.defer

Go语言中的defer语句会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时,将延迟处理的语句按defer定义的逆序进行执行,也就是说,先被defer的语句最后被执行,最后被defer的语句,最先被执行。

package mainimport "fmt"func main() {fmt.Println("开始")defer fmt.Println(1)defer fmt.Println(2)defer fmt.Println(3)fmt.Println("结束")
}

结果:

开始
结束
3
2
1

由于defer语句延迟调用的特性,所以defer语句能非常方便的处理资源释放问题。比如:资源清理、文件关闭、解锁及记录时间等👕

defer执行时机

在Go语言的函数中return语句在底层并不是原子操作,它分为给返回值赋值和RET指令两步。而defer语句执行的时机就在返回值赋值操作后,RET指令执行前。具体如下图所示:

在这里插入图片描述


4.内置函数

在这里插入图片描述

panic/recover

Go语言中目前(Go1.12)是没有异常机制,但是使用panic/recover模式来处理错误。 panic可以在任何地方引发,但recover只有在defer调用的函数中有效。 首先来看一个例子:

package mainimport "fmt"func funcA() {fmt.Println("func A")
}func funcB() {panic("panic in B")
}func funcC() {fmt.Println("func C")
}
func main() {funcA()funcB()funcC()
}

输出:

func A
panic: panic in Bgoroutine 1 [running]:
main.funcB(...)D:/SystemData/mine/Go-Page/hello.go:10
main.main()D:/SystemData/mine/Go-Page/hello.go:18 +0x66Process finished with the exit code 2

程序运行期间funcB中引发了panic导致程序崩溃,异常退出了。这个时候我们就可以通过recover将程序恢复回来,继续往后执行。

package mainimport "fmt"func funcA() {fmt.Println("func A")
}func funcB() {defer func() {err := recover()if err != nil {fmt.Println("recover in B")}}()panic("panic in B")
}func funcC() {fmt.Println("func C")
}
func main() {funcA()funcB()funcC()// func A// recover in B// func C
}
  • recover()必须搭配defer使用
  • defer一定要在可能引发panic的语句之前定义

相关内容

热门资讯

安卓系统的经典铃声,唤醒回忆的... 你有没有发现,手机里那些熟悉的铃声,有时候就像老朋友一样,陪伴着我们度过了无数个日日夜夜?今天,就让...
鸿蒙系统还是安卓系统号,系统之... 你有没有想过,手机里的操作系统就像是我们的大脑,它决定了我们手机能做什么,不能做什么。现在,就让我们...
安卓系统装贝达,安卓系统下的贝... 你有没有想过,你的安卓手机装上贝达系统后,会有怎样的奇妙体验呢?想象你的手机瞬间变身,变得流畅无比,...
安卓系统沃尔沃音响设置,轻松享... 你有没有发现,自从你的安卓手机和沃尔沃音响完美结合后,开车时的音乐体验简直就像是在音乐厅里一样?没错...
米10系统基于安卓,基于安卓的... 你知道吗?最近手机圈里可是热闹非凡呢!小米10这款手机,自从发布以来就吸引了无数人的目光。而它所搭载...
命令安卓系统怎么卸载,安卓系统... 手机里装了太多不用的应用,是不是感觉手机都快要爆炸了?别急,今天就来教你怎么轻松卸载安卓系统中的应用...
安卓系统安装小学教材,安卓系统... 你有没有想过,手机里的安卓系统竟然能装上小学教材呢?没错,你没听错!在这个信息爆炸的时代,科技的发展...
华为安卓系统锁住了,揭秘锁屏背... 最近是不是发现你的华为手机有点儿“顽皮”了?它突然间变得神秘起来,屏幕上那个熟悉的安卓系统仿佛被施了...
安卓电脑改苹果系统,跨越平台的... 你有没有想过,把你的安卓电脑改头换面,变成一个优雅的苹果系统使用者呢?想象那流畅的界面,那独特的触控...
安卓系统怎么按后台,并在任务完... 你有没有遇到过这种情况:手机屏幕一黑,安卓系统就自动进入后台了?是不是觉得有点小郁闷,想要手动切换回...
2021年安卓系统ui,202... 你有没有发现,手机界面最近好像换了个模样?没错,2021年的安卓系统UI可是来了一场大变身呢!今天,...
安卓系统程序编写软件,打造个性... 你有没有想过,手机里的那些神奇应用是怎么诞生的呢?没错,就是那些让你在闲暇时光刷刷视频、在通勤路上玩...
自动开机安卓系统,智能生活新篇... 你有没有想过,当你的安卓手机在清晨的第一缕阳光照耀下自动开机,那种轻松自在的感觉?想象不用再手动解锁...
真我平板x安卓系统,畅享智能生... 亲爱的读者们,你是否也在寻找一款既能满足你对平板电脑的期待,又能让你畅享安卓系统带来的无限乐趣的设备...
恒星安卓系统官网,引领未来智能... 亲爱的读者们,你是否曾好奇过那些闪耀在夜空中的星星,它们是如何在浩瀚的宇宙中熠熠生辉的呢?今天,我要...
u8安卓系统,功能与特色深度解... 你知道吗?在手机操作系统界,有一个小家伙可是相当受欢迎的,它就是U8安卓系统。今天,就让我带你来一探...
花椒安卓系统美颜功能,打造完美... 你有没有发现,现在拍照已经不仅仅是记录生活的工具了,它更是一种艺术创作呢!而在这其中,花椒安卓系统的...
戴尔平板升级安卓系统,畅享安卓... 你有没有发现,戴尔平板最近好像悄悄地来了一次大变身?没错,就是那个我们熟悉的戴尔平板,它现在竟然可以...
安卓助手怎么升级系统,畅享最新... 亲爱的安卓用户们,你是否也和我一样,对安卓系统的升级充满了期待和好奇呢?每次系统升级,都仿佛是给我们...
国产安卓系统的发展,国产安卓系... 你知道吗?在我国科技飞速发展的今天,国产安卓系统可是越来越受到大家的关注呢!它就像一颗冉冉升起的新星...