Go 語(yǔ)言的函數(shù)是“一等公民”?
1.介紹
在 Go 語(yǔ)言中,函數(shù)被稱為“一等公民”。實(shí)際上,在其它編程語(yǔ)言中,也有此說(shuō)法,例如 JavaScript。
什么是編程語(yǔ)言的“一等公民”?Ward Cunningham 的解釋如下:
如果對(duì)如何創(chuàng)建和使用它沒(méi)有任何限制:當(dāng)該結(jié)構(gòu)可以被視為沒(méi)有限制的值時(shí),該語(yǔ)言結(jié)構(gòu)被稱為該語(yǔ)言中的 FirstClass 值。
A language construct is said to be a FirstClass value in that language when there are no restrictions on how it can be created and used: when the construct can be treated as a value without restrictions.
“一等公民”的特性是可以存儲(chǔ)在變量中,可以作為參數(shù)傳遞給函數(shù),可以在函數(shù)中創(chuàng)建并作為返回值從函數(shù)返回。
FirstClass features can be stored in variables, passed as arguments to functions, created within functions and returned from functions. In dynamically typed languages, a FirstClass feature can also have its type examined at run-time.
本文我們介紹一下 Go 語(yǔ)言的函數(shù)是否符合“一等公民”的特性。
2.存儲(chǔ)在變量中
Go 語(yǔ)言的函數(shù)可以作為變量的值,存儲(chǔ)在變量中。
func main() {
var hello = func(name string) { fmt.Printf("hello %s\n", name) }
hello("gopher")
}
閱讀上面這段代碼,我們定義一個(gè)變量 hello,和一個(gè)匿名函數(shù),將匿名函數(shù)賦值給變量 hello,我們可以通過(guò)變量調(diào)用該匿名函數(shù)。
3.作為參數(shù)傳遞給其他函數(shù)
Go 語(yǔ)言的函數(shù)可以作為參數(shù),傳遞給其他函數(shù)。
https://back-media.51cto.com/editor?id=704975/h6e90be6-6IhK9UNI
閱讀上面這段代碼,我們定義三個(gè)函數(shù),分別是 Circle、areaOfCircle 和 perimeterOfCircle,其中 areaOfCircle 和 perimeterOfCircle 作為 Circle 的參數(shù),分別用于計(jì)算面積和周長(zhǎng)。
4.可以在函數(shù)中創(chuàng)建,并作為返回值
Go 語(yǔ)言的函數(shù)可以在函數(shù)體中創(chuàng)建,并作為返回值從函數(shù)體中返回。
func main() {
calcArea := CircleCalc("area")
fmt.Println(calcArea(5))
calcPerimeter := CircleCalc("perimeter")
fmt.Println(calcPerimeter(5))
}
func CircleCalc(s string) func(float64) float64 {
switch s {
case "area":
return func(r float64) float64 {
return math.Pi * r * r
}
case "perimeter":
return func(r float64) float64 {
return 2 * math.Pi * r
}
default:
return nil
}
}
閱讀上面這段代碼,我們定義一個(gè)函數(shù) CircleCalc,在其函數(shù)體中定義兩個(gè)匿名函數(shù),并將匿名函數(shù)作為返回值從函數(shù)體中返回。
5.總結(jié)
本文我們通過(guò)三段示例代碼,證明 Go 語(yǔ)言中函數(shù)符合“一等公民”的特性,我們可以使用這些特性,使業(yè)務(wù)代碼更加簡(jiǎn)潔。