如何理解Go函數是一等公民原理及使用場景
引言
在接觸Go這么語言,可能你經常會聽到這樣一句話。Go語言中,函數屬于一等公民,你可能很費解,什么是一等公民。是因為函數的優(yōu)先級很高嗎?如果是又是怎樣的優(yōu)先級呢?本文將分享Go語言中函數是一等公民的真正面紗。
什么是函數
在了解一等公民之前,先普及一下函數基礎知識。函數是執(zhí)行某種特定功能的代碼塊,一個較大的程序一般應分為若干個程序塊,每一個模塊用來實現一個特定的功能,這里的模塊就可以稱之為函數。
//?函數的定義 func?FunName(變量名?變量類型...)?(返回類型...)?{ ????return?返回值... }
在Go語言中,函數可以分配給一個變量,可以作為函數的參數,也可以作為函數的返回值。這樣的行為就可以理解為函數屬于一等公民。
函數使用場景
匿名函數
通過匿名函數的形式,將一個函數分配給一個變量。
package?main import?(?? ????"fmt" ) func?main()?{?? ????a?:=?func()?{ ????????fmt.Println("hello?world?first?class?function") ????} ????a() ????fmt.Printf("%T",?a) }
在上面的程序中,我們?yōu)榈?8 行中的變量分配了一個函數。這是將函數分配給變量的語法。如果您仔細注意,分配給的函數沒有名稱。這些類型的函數稱為匿名函數,因為它們沒有名稱。
也可以調用匿名函數而不將其分配給變量。讓我們在下面的示例中看看這是如何完成的。
package?main import?(?? ????"fmt" ) func?main()?{?? ????func()?{ ????????fmt.Println("hello?world?first?class?function") ????}() }
在上面的程序中,在第 8 行中定義了一個匿名函數,緊接著函數定義之后,我們使用第10行("()")調用該函數。
自定義函數類型
就像我們定義自己的結構類型一樣,也可以定義自己的函數類型。
type?add?func(a?int,?b?int)?int
上面的代碼片段創(chuàng)建了一個新的函數類型,它接受兩個整數參數并返回一個整數?,F在我們可以定義類型的變量。
package?main import?(?? ????"fmt" ) type?add?func(a?int,?b?int)?int func?main()?{?? ????var?a?add?=?func(a?int,?b?int)?int?{ ????????return?a?+?b ????} ????s?:=?a(5,?6) ????fmt.Println("Sum",?s) }
在上面的程序中,在第 10 行,我們定義了一個變量 type,并為其賦值一個簽名與類型匹配的函數。我們調用第 13 行中的函數并將結果分配給s變量。將打印結果:
Sum 11
函數作為參數
在Go語言中,也是支持將函數作為另外一個函數的參數進行傳遞。
package?main import?(?? ????"fmt" ) func?simple(a?func(a,?b?int)?int)?{?? ????fmt.Println(a(60,?7)) } func?main()?{?? ????f?:=?func(a,?b?int)?int?{ ????????return?a?+?b ????} ????simple(f) }
在上面的示例中,在第 7 行中,我們定義了一個函數,該函數接受一個接受兩個 int 參數并返回一個 int 作為參數的函數。在第 12 行的 main 函數中,我們創(chuàng)建了一個匿名函數,其簽名與函數的參數匹配。我們在下一行中調用 and 傳遞作為參數。
函數作為返回值
在Go語言中,也可以將函數作為另外一個函數的返回值進行傳遞。
package?main import?(?? ????"fmt" ) func?simple()?func(a,?b?int)?int?{?? ????f?:=?func(a,?b?int)?int?{ ????????return?a?+?b ????} ????return?f } func?main()?{?? ????s?:=?simple() ????fmt.Println(s(60,?7)) }
在上面的程序中,第 7 行中的簡單函數返回一個函數,該函數接受兩個參數并返回。
閉包
閉包是匿名函數的特例。閉包是匿名函數,用于訪問在函數主體外部定義的變量。
package?main import?(?? ????"fmt" ) func?main()?{?? ????a?:=?5 ????func()?{ ????????fmt.Println("a?=",?a) ????}() }
在上面的程序中,匿名函數訪問變量,該變量存在于其主體之外的第 10 行。因此,這個匿名函數是一個閉包。
實戰(zhàn)演示
上面提到了一些函數相關的知識,這里以函數作為形參演示一個demo。
將函數作為參數,將數組中的每一個元素都 * 5。
package?main import?"fmt" func?sum(array?[3]int,?f?func(int)int)?[3]int?{ ????newArray?:=?[3]int{0,?0,?0} ????for?k,?v?:=?range?array?{ ????????newArray[k]?=?f(v) ????} ????return?newAarray } func?main()?{ ????a?:=?[3]int{1,?2,?3} ????sum(a,?func(n?int)?int?{ ????????return?n?*?5 ????}) }
以上就是如何理解Go函數是一等公民原理及使用場景的詳細內容,更多關于Go函數一等公民的資料請關注腳本之家其它相關文章!
相關文章
golang 輸出重定向:fmt Log,子進程Log,第三方庫logrus的詳解
這篇文章主要介紹了golang 輸出重定向:fmt Log,子進程Log,第三方庫logrus的詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12詳解Golang中errors包如何返回自定義error類型
這篇文章主要為大家詳細介紹了Golang中errors包如何返回自定義error類型,文中的示例代碼簡潔易懂,有需要的小伙伴可以跟隨小編一起學習一下2023-09-09