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