Go 分布式学习利器(8)-- Go的函数
生活随笔
收集整理的這篇文章主要介紹了
Go 分布式学习利器(8)-- Go的函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1. Go語言的函數語法
- 2. Go 函數中的可變長參數
- 3. Go函數中的延遲函數 deffer
1. Go語言的函數語法
先介紹一下Go語言的函數和其他語言 函數之間的差異,其中有一些已經在之前的總結中提到過。
函數在Go語言中是屬于一等公民。
- 可以有多個返回值
- 所有參數都是值傳遞:slice ,map, channel 會有傳引用的錯覺
- 函數可以作為變量的值
- 函數可以作為參數和返回值
比如如下測試函數:
func returnMultiValue() (int, int) {return rand.Intn(10), rand.Intn(20) // 兩個返回值
}func TestFunction(t *testing.T) {a,_ := returnMultiValue() // 可以通過 符號 '_' 來表示不獲取第一或第二個返回值t.Log(a)
}
輸出如下:
=== RUN TestFunctionTestFunction: function_test.go:16: 1
--- PASS: TestFunction (0.00s)
函數作為變量,參數,以及返回值
編寫如下幾個測試函數:
/*
通過函數式編程
以下是一個計時函數,統計函數執行耗時的函數
入參:函數
返回值:函數可以統計任意 函數的執行時間,只需要將被統計函數名稱作為入參傳入該函數即可
*/
func calcTimeSpent(inner func(op int) int) func(op int) int{return func(n int) int{start := time.Now() // 開始計時ret := inner(n) // 執行函數fmt.Println("time spent :", time.Since(start).Seconds()) // 統計計時return ret}
}func slowTest(op int) int {time.Sleep(time.Second * 1) // sleep 1秒return op
}func TestSpentTime(t *testing.T) {sp := calcTimeSpent(slowTest) // 傳入耗時函數t.Log(sp(10))
}
輸出如下:
=== RUN TestSpentTime
time spent : 1.004237117TestSpentTime: function_test.go:36: 10
--- PASS: TestSpentTime (1.00s)
2. Go 函數中的可變長參數
基本語法如下:
func sum( args ... int) int{s := 0for _,op := range args{s += op}return s
}
相同類型的參數不再需要指定具體的個數,只需要傳入’…’ 即可被轉化為一個參數數組完成函數內部的邏輯處理需要,減少實際開發過程相同類型函數的重寫或者重載的代碼量。
測試以上變參 函數如下:
func sum(args ... int) int {s := 0for _,op := range args{ //將傳入的參數轉換為數組s += op}return s
}func TestChangeArgs(t *testing.T) {t.Log(sum(1,2,3)) // 可以傳入3 個,或者 下面的4個參數t.Log(sum(4,16,8,9))
}
最終的輸出如下:
=== RUN TestChangeArgsTestChangeArgs: function_test.go:57: 6TestChangeArgs: function_test.go:58: 37
--- PASS: TestChangeArgs (0.00s)
3. Go函數中的延遲函數 deffer
通過defer關鍵字聲明一個函數,用來表示這個函數屬于一個延遲函數。
即使函數在執行過程中異常退出,該函數調用的deffer函數也會正常執行(這個機制的實現還是比較有趣的,有點像C++的智能指針)。
利用延遲執行的機制,能夠完成應用的垃圾回收功能。
關于deffer函數的測試代碼如下:
func DefferFun() {fmt.Println("defer func run")
}
func TestDeferFun(t *testing.T) {defer DefferFun()t.Log("Started")panic("Failed") // panic 表示不可修復的錯誤,會讓當前程序停止執行,并退出,但這里不影響defer函數的執行。fmt.Println("end")`在這里插入代碼片`
}
輸出如下:
=== RUN TestDeferFunTestDeferFun: function_test.go:66: Started
defer func run
--- FAIL: TestDeferFun (0.00s)
panic: Failed [recovered]panic: Failed
如果將panic函數去掉,讓程序正常執行,可以看到defer函數是在所有函數執行完成之后才會輸出。
=== RUN TestDeferFunTestDeferFun: function_test.go:66: Started
end
defer func run #所有函數邏輯執行完成 之后才執行
--- PASS: TestDeferFun (0.00s)
可以看到defer 即使延遲執行,仍然可以在發生panic 異常的時候正常輸出。
總結
以上是生活随笔為你收集整理的Go 分布式学习利器(8)-- Go的函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Go 分布式学习利器(7)-- 字符串
- 下一篇: Go 分布式学习利器(9)-- Go语言