為什么函數(shù)是一等公民

這篇文章主要講解了“為什么函數(shù)是一等公民”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“為什么函數(shù)是一等公民”吧!

為企業(yè)提供成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站優(yōu)化、全網(wǎng)整合營(yíng)銷推廣、競(jìng)價(jià)托管、品牌運(yùn)營(yíng)等營(yíng)銷獲客服務(wù)。創(chuàng)新互聯(lián)擁有網(wǎng)絡(luò)營(yíng)銷運(yùn)營(yíng)團(tuán)隊(duì),以豐富的互聯(lián)網(wǎng)營(yíng)銷經(jīng)驗(yàn)助力企業(yè)精準(zhǔn)獲客,真正落地解決中小企業(yè)營(yíng)銷獲客難題,做到“讓獲客更簡(jiǎn)單”。自創(chuàng)立至今,成功用技術(shù)實(shí)力解決了企業(yè)“網(wǎng)站建設(shè)、網(wǎng)絡(luò)品牌塑造、網(wǎng)絡(luò)營(yíng)銷”三大難題,同時(shí)降低了營(yíng)銷成本,提高了有效客戶轉(zhuǎn)化率,獲得了眾多企業(yè)客戶的高度認(rèn)可!

關(guān)于一等公民[1](First-class citizen)看看維基百科的定義:

In programming language design, a first-class citizen (also type, object,  entity, or value) in a given programming language is an entity which supports  all the operations generally available to other entities. These operations  typically include being passed as an argument, returned from a function,  modified, and assigned to a variable.

大意是說,在編程語言中,所謂一等公民,是指支持所有操作的實(shí)體, 這些操作通常包括作為參數(shù)傳遞,從函數(shù)返回,修改并分配給變量等。

比如 int 類型,它支持作為參數(shù)傳遞,可以從函數(shù)返回,也可以賦值給變量,因此它是一等公民。

類似的,函數(shù)是一等公民,意味著可以把函數(shù)賦值給變量或存儲(chǔ)在數(shù)據(jù)結(jié)構(gòu)中,也可以把函數(shù)作為其它函數(shù)的參數(shù)或者返回值。關(guān)于函數(shù)是一等公民,在維基百科也有定義[2]。

In computer science, a programming language is said to have first-class  functions if it treats functions as first-class citizens. This means the  language supports passing functions as arguments to other functions, returning  them as the values from other functions, and assigning them to variables or  storing them in data structures. Some programming language theorists require  support for anonymous functions (function literals) as well.In languages with  first-class functions, the names of functions do not have any special status;  they are treated like ordinary variables with a function type. The term was  coined by Christopher Strachey in the context of "functions as first-class  citizens" in the mid-1960s.

函數(shù)作為一等公民的概念是 1960 年由英國(guó)計(jì)算機(jī)學(xué)家 Christopher Strachey[3]  提出來的。然而,并非所有語言都將函數(shù)作為一等公民,特別是早期,比如 C 語言中函數(shù)就不是一等公民,一些功能通過函數(shù)指針來實(shí)現(xiàn)的;再比如 C++、Java  等,都是后來的版本才加上的。

一般來說,函數(shù)式編程語言、動(dòng)態(tài)語言和現(xiàn)代的編程語言,函數(shù)都會(huì)作為一等公民,比如:Scala、Julia 等函數(shù)式語言,JavaScript、Python  等動(dòng)態(tài)語言,Go、Rust、Swift 等現(xiàn)代的編譯型語言。

為了讓大家對(duì)函數(shù)是一等公民有更深的理解,針對(duì)上文提到的一等公民的一等功能,我們看看 Go 語言是如何支持的。

匿名函數(shù)

函數(shù)一般是有名字的,但有時(shí)候沒有名字的函數(shù)更簡(jiǎn)潔、好用。沒有名字的函數(shù)叫匿名函數(shù)。

以下是 Go 語言匿名函數(shù)的一個(gè)例子:

package main  import (  "fmt" )  func main() {  fn := func() {   fmt.Println("This is anonymous function!")  }  fn()   fmt.Printf("The type of fn: %T\n", fn) }  // output: // This is anonymous function! // The type of fn: func()

在線運(yùn)行:https://play.studygolang.com/p/IcInzZsAr0a。

在 Go 中,匿名函數(shù)最常使用的場(chǎng)景是開啟一個(gè) goroutine,經(jīng)常會(huì)見到類似這樣的代碼:

go func() {   // xxxx }()

這里匿名函數(shù)定義后立即調(diào)用。此外,defer 語句中也常見。

定義函數(shù)類型

定義函數(shù)類型和其他類型類似,同時(shí)后半部分和匿名函數(shù)類似,只不過沒有函數(shù)實(shí)現(xiàn)。比如 net/http 包中的 HandlerFunc  函數(shù)類型:

type HandlerFunc func(ResponseWriter, *Request)

怎么使用這個(gè)類型?能看懂這樣的代碼,表示你理解了:

var h http.HandlerFunc = func(w ResponseWriter, req *Request) {   fmt.Fprintln(w, "Hello World!") }

函數(shù)作為參數(shù)

意思是說,一個(gè)函數(shù)作為另一個(gè)函數(shù)的參數(shù),也就是回調(diào),在 JS 中很常見。在 Go 語言中也經(jīng)常出現(xiàn)。文章開頭的問題就是函數(shù)作為參數(shù)。根據(jù)  Gin 的 API 定義,router.GET 方法的簽名如下:

func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes

其中 HandlerFunc 是一個(gè)函數(shù)類型,它的定義如下:

type HandlerFunc func(*Context)

所以,router.GET("/users", Users) 中,Users 只是 GET 函數(shù)的參數(shù),參數(shù)類型是 HandlerFunc,而 Users  的定義只要符合 HandlerFunc 即可:

func Users(ctx *gin.Context) {}

因?yàn)檫@里將函數(shù) Users 作為參數(shù),所以自然不需要給 Users 傳遞參數(shù),Uers 的調(diào)用有 GET 內(nèi)部負(fù)責(zé),即所謂的回調(diào)。

函數(shù)作為返回值

函數(shù)作為返回值,在 Go 中,這樣的函數(shù)一定是匿名函數(shù)。在進(jìn)行 Web 開發(fā)時(shí),中間件就會(huì)使用上函數(shù)作為返回值,還是以 Gin  為例,定義一個(gè) Logger 中間件:

func Logger() gin.HandlerFunc {  return func(c *gin.Context) {   t := time.Now()    // Set example variable   c.Set("example", "12345")    // before request    c.Next()    // after request   latency := time.Since(t)   log.Print(latency)    // access the status we are sending   status := c.Writer.Status()   log.Println(status)  } }

從上文知道,gin.HandlerFunc 是一個(gè)函數(shù)類型,因此需要返回一個(gè)該類型的實(shí)例,而匿名函數(shù)(函數(shù)字面值)只要和 gin.HandlerFunc  類型的底層類型一致,會(huì)進(jìn)行隱式轉(zhuǎn)換,所以可以直接返回 func(c *gin.Context) {} 這個(gè)匿名類型。

經(jīng)常聽到高階函數(shù),函數(shù)是一等公民,就支持高階函數(shù)。一個(gè)函數(shù)只要接收一個(gè)或多個(gè)函數(shù)類型參數(shù);亦或是返回一個(gè)函數(shù),這樣的函數(shù)就叫做高階函數(shù)。

閉包

閉包(Closure)是匿名函數(shù)的一個(gè)特例。當(dāng)一個(gè)匿名函數(shù)所訪問的變量定義在函數(shù)體的外部時(shí),就稱這樣的匿名函數(shù)為閉包。

一個(gè)簡(jiǎn)單的例子:

package main  import (       "fmt" )  func main() {       a := 5     func() {         fmt.Println("a =", a)     }() }

在上面的程序中,匿名函數(shù)在第 10 行訪問了變量 a,而 a 存在于函數(shù)體的外部。因此這個(gè)匿名函數(shù)就是閉包。

感謝各位的閱讀,以上就是“為什么函數(shù)是一等公民”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)為什么函數(shù)是一等公民這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

網(wǎng)頁名稱:為什么函數(shù)是一等公民
標(biāo)題路徑:http://muchs.cn/article26/jepjjg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈定制開發(fā)、網(wǎng)站排名、網(wǎng)頁設(shè)計(jì)公司商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計(jì)公司