網站首頁 編程語言 正文
「1. 用type關鍵字可以定義函數類型,函數類型變量可以作為函數的參數或返回值。」
package?main import?"fmt" func?add(a,?b?int)?int?{ ?return?a?+?b } func?sub(a,?b?int)?int?{ ?return?a?-?b } type?Task?func(int,?int)?int func?exec(t?Task,?a,?b?int)?int?{ ?return?t(a,?b) } func?main()?{ ?a?:=?exec(add,?10,?20) ?fmt.Println(a) ?b?:=?exec(sub,?100,?95) ?fmt.Println(b) }
解析:type Task func(int, int) int,這句是說,使用type關鍵字定義1個類型為func的Task,這個func有2個int形參、1個int返回值。再看exec這個函數,它有3個形參,形參t的類型是剛定義的函數類型Task,另外兩個你懂的,我就不說了。
「2. 匿名函數的玩法是真的騷,看看騷在哪里」
栗子1:匿名函數可以直接賦給變量
func?main()?{ ?var?aaa?=?func(a,?b?int)?int?{ ??return?a?+?b ?} ?ret?:=?aaa(89,?78) ?fmt.Println(ret) }
輸出:
167
栗子2:匿名函數作為函數入參
這個例子感覺跟剛才使用type關鍵字定義函數類型的例子有點相同的趕腳,仔細一看,好像也只是在使用的方式上是一樣,定義函數的套路又是不同的。
func?work(f?func(int,?int)?int,?a,?b?int)?int?{ ?return?f(a,?b) } func?add(a,?b?int)?int?{ ?return?a?+?b } func?main()?{ ?a?:=?work(add,?100,?200) ?fmt.Println(a) }
輸出:
300
解析:形參f的類型就是匿名函數,繼續看func(int, int) int,這個匿名函數接收兩個int形參,返回值也是int類型。另外兩個形參a和b,也是int,想必你懂了,我就不廢話了。
栗子3:匿名函數作為函數出參
匿名函數作為函數出參(作為函數返回值),經不斷調測,有3種騷包玩法
騷包玩法1
//?先來個簡單的 func?work()?func()?int?{ ?return?func()?int?{ ??return?10?+?20 ?} } func?main()?{ ?f?:=?work() ?ret?:=?f() ?fmt.Println(ret) }
輸出:
30
騷包玩法2
//?再改造下 func?work(a,?b?int)?func()?int?{ ?return?func()?int?{ ??return?a?+?b ?} } func?main()?{ ?f?:=?work(500,?20) ?ret?:=?f() ?fmt.Println(ret) }
輸出:
520
騷包玩法3
//?再次改造 func?work()?func(int,?int)?int?{ ?return?func(a,?b?int)?int?{ ??return?a?+?b ?} } func?main()?{ ?f?:=?work() ?ret?:=?f(600,?50) ?fmt.Println(ret) }
輸出:
650
對3種騷包玩法的簡單解析:
再這里就解析一下第3種玩法,能搞懂這個玩法,前面2個玩法,你就自然懂了。work函數沒有入參,但是有出參(也可以說是返回值),出參是匿名函數func(int, int) int,這個定義在返回值里的匿名函數有2個int類型的形參(入參)和1個int類型的返回值。再看看函數體內部,沒干很復雜活兒,而是直接return了匿名函數,函數體里的這個匿名函數是和定義在返回值里的類型保持一致的,也是接收了2個int的形參a和b,返回值也是int,啥也沒干,就做了個相加。好郁悶!不知道你看懂了沒?再看看是如何使用work函數的,關鍵點就在這里,調用work()賦給了變量f,這時候,f它就是一個函數了,再調用f(600, 50),想必你已經知道了為啥要傳入2個int值,這下搞定!不知道把你繞暈沒,這玩法確實很騷。
「3. 匿名函數和延遲調用」
延遲調用的規則是:按照「先進后出」的順序,也就是說函數返回前是會被執行的,而且是按照先進后出的順序。如何起到延遲的效果,是需要注冊的,可通過defer關鍵字進行注冊。那么什么場景下需要用到延遲調用呢?比如常見的場景:當一個函數被即將執行完后,也就是完成任務的最后一刻,需要回收和釋放某些資源。
延遲調用的機制可以配合匿名函數來使用,這樣就可以讓匿名函數被直接調用,只能說是真的騷。
先看個小栗子:
package?main import?"fmt" func?work()?bool?{ ?fmt.Println("函數開始工作...") ?defer?func()?{ ??fmt.Println("回收相關資源工作開始!") ?}() ?defer?func()?{ ??fmt.Println("清理工作開始!") ?}() ?fmt.Println("函數正在工作...") ?fmt.Println("函數工作完畢...") ?return?true } func?main()?{ ?status?:=?work() ?fmt.Println(status) }
輸出:
函數開始工作...
函數正在工作...
函數工作完畢...
清理工作開始!
回收相關資源工作開始!
true
在上面的栗子中,定義了個work函數,先看看輸出的結果,感受下。在work函數中,注冊了兩個延遲調用,work函數從開始->正在->完畢,結束后才執行defer注冊的匿名函數,這里要著重注意延遲調用規則:「先進后出」,也就是先注冊后執行。“回收相關資源工作”是先注冊的,他的執行順序排在了“清理工作”的后面。感受到了嗎?
最后說明一下:defer關鍵字讓匿名函數實現了可直接調用,那么使用defer注冊延遲調用時要注意,defer關鍵字的后面一定是要函數或方法的調用,不能直接寫語句哦。
原文鏈接:https://mp.weixin.qq.com/s/DtSWp-APaAPmTG1mjAMRQQ
相關推薦
- 2022-07-25 C++數據結構之雙向鏈表_C 語言
- 2022-10-16 Python?讀取?Word?文檔操作_python
- 2023-03-20 C#實現拷貝文件到另一個文件夾下_C#教程
- 2024-01-28 在已有git倉庫的情況下,如何提交修改后的文件
- 2023-12-23 mybatis的selectOne()方法使用記錄
- 2022-08-20 Redis實現庫存扣減的解決方案防止商品超賣_Redis
- 2022-05-21 kubernetes?k8s入門定義一個Pod_云其它
- 2022-05-09 Redis擊穿穿透雪崩產生原因分析及解決思路面試_Redis
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支