一篇文章帶你了解Go語言基礎之函數(shù)(下篇)
上次主要回顧
上述我們知道,定義一個函數(shù),可以將函數(shù)內(nèi)存分配理解如下。
同時我們也知道,無論進行什么操作,只會操作棧上面的值。
函數(shù)和變量
函數(shù)名即變量
不知道你想過沒,定義一個變量,接收一個函數(shù),就像這樣。
- package main
- import "fmt"
- func say() {
- fmt.Println("say")
- }
- func main() {
- var s1 = say
- s1()
- }
執(zhí)行結果如下。
可以發(fā)現(xiàn),通過一個變量接收一個函數(shù)名,在通過變量名+括號執(zhí)行,是沒有問題的。
那么,這個變量是什么類型的呢???
- fmt.Printf("%T\n",s1)
執(zhí)行結果
如果我將say函數(shù)改一下呢?
- func say(s int) int{
- fmt.Println("say")
- return 1
- }
- fmt.Printf("%T\n",s1)
可以發(fā)現(xiàn),如果函數(shù)參數(shù)和返回值不一樣,打印出來的類型也是不一樣的。
定義函數(shù)類型
上述我們知道,可以通過變量接收一個函數(shù)名。
通過變量接收函數(shù)名是沒有約束的,不管函數(shù)幾個參數(shù),幾個返回值,都可以接收,真是活出了動態(tài)語言的樣子。
而定義函數(shù)類型就是限制變量接收函數(shù),只能接收指定格式的函數(shù)。
主要用到type關鍵字。
格式
- type 變量名 func([參數(shù)類型,參數(shù)類型]) [返回值類型]
- 中括號表示可選參數(shù)
例如
- type a func()
- type b func(int)
- type a func(int,int) int
具體代碼
- package main
- import "fmt"
- /*
- 定義一個函數(shù)類型的變量
- 接收的函數(shù)參數(shù)必須是兩個int類型
- 函數(shù)的返回值也必須是int類型
- */
- type cType func(int, int) int
- func say1(a, b int) int {
- fmt.Println("say",a+b)
- return 1
- }
- func say2(a, b int) {
- fmt.Println("say")
- }
- func main() {
- var s1 cType
- s1 = say1//調(diào)用s1其實調(diào)用的就是say1
- s1(1,1)
- //var s2 cType
- //s2 = say2//報錯,cannot use say2 (type func(int, int)) as type cType in assignment
- }
高階函數(shù)
千萬不要被這個名字唬住了。
簡單點說,高階函數(shù)就是把函數(shù)當作參數(shù)或者把函數(shù)當作返回值。
函數(shù)當作參數(shù)
- package main
- import "fmt"
- func add(x int, y int) int {
- return x + y
- }
- func calc(x int, y int, other func(int, int) int) int {
- return other(x, y)
- }
- func main() {
- //將add函數(shù)傳入第三個參數(shù)
- var result = calc(34, 12, add)
- fmt.Println(result)
- }
函數(shù)當作返回值
- package main
- import "fmt"
- func add(x int, y int) int {
- return x + y
- }
- func test() (func(int, int) int) {
- return add
- }
- func main() {
- var a = test()
- fmt.Println(a(1,2))
- }
至于上述兩個的功能,恕小生不才,至今用到的場景不多。
匿名函數(shù)
匿名函數(shù)顧名思義,就是沒有名字的函數(shù)。
- func([參數(shù),參數(shù)...])[(返回值,返回值)]{
- 代碼
- }()
- //匿名函數(shù)后面必須跟括號,直接執(zhí)行
//匿名函數(shù)后面必須跟括號,直接執(zhí)行
例如
- func() {
- }()
- func(x int, y int) (int) {
- return x + y
- }()
代碼
- package main
- import "fmt"
- func main() {
- //s1等于一個匿名函數(shù),并且直接執(zhí)行
- var s1 = func(x int, y int) (int) {
- return x + y
- }(1,2)
- fmt.Println(s1)
- }
閉包
閉包,這個有點不太理解,簡單點說就是函數(shù)里面套了一個函數(shù),里面函數(shù)引用的外面函數(shù)的變量。
示例
- package main
- import "fmt"
- func other() func() {
- //返回的是一個函數(shù)類型
- var a = 666
- return func() {
- //內(nèi)部函數(shù)使用的是外面函數(shù)的a
- fmt.Println(a)
- }
- }
- func main() {
- var o = other()
- o()
- }
執(zhí)行結果。
結果是沒有問題的。
雖然我們以前學過,函數(shù)執(zhí)行完畢后,里面的變量會回收。
但是在用到閉包時,可以這樣理解,里面函數(shù)使用了外面函數(shù)的變量,那這個變量就不會被回收。
總結
本文主要講述了函數(shù)及變量,高階函數(shù),匿名函數(shù),閉包,其中閉包是比較難以理解的,一定要花點心思。寶劍鋒從磨礪出,梅花香自苦寒來,一定要多多實踐。
如果在操作過程中有任何問題,記得下面留言,我們看到會第一時間解決問題。我是碼農(nóng)星期八,如果覺得還不錯,記得動手點贊一下哈。感謝你的觀看。