av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

學(xué)習(xí)Scala的閉包

到本章這里,所有函數(shù)文本的例子僅參考了傳入的參數(shù)。例如,(x: Int) => x > 0里,函數(shù)體用到的***變量,x > 0,是x,被定義為函數(shù)參數(shù)。然而也可以參考定義在其它地方的變量:

員工經(jīng)過長期磨合與沉淀,具備了協(xié)作精神,得以通過團(tuán)隊(duì)的力量開發(fā)出優(yōu)質(zhì)的產(chǎn)品。創(chuàng)新互聯(lián)堅(jiān)持“專注、創(chuàng)新、易用”的產(chǎn)品理念,因?yàn)椤皩W⑺詫I(yè)、創(chuàng)新互聯(lián)網(wǎng)站所以易用所以簡單”。公司專注于為企業(yè)提供成都網(wǎng)站制作、成都做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè)、微信公眾號(hào)開發(fā)、電商網(wǎng)站開發(fā),小程序定制開發(fā),軟件按需定制設(shè)計(jì)等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。

 
 
 
  1. (x: Int) => x + more // more是多少? 

編輯推薦:Scala編程語言專題

函數(shù)把“more”加入?yún)⒖?,但什么是more呢?從這個(gè)函數(shù)的視點(diǎn)來看,more是個(gè)自由變量:free variable,因?yàn)楹瘮?shù)文本自身沒有給出其含義。相對(duì)的,x變量是一個(gè)綁定變量:bound variable,因?yàn)樗诤瘮?shù)的上下文中有明確意義:被定義為函數(shù)的***參數(shù),一個(gè)Int。如果你嘗試獨(dú)立使用這個(gè)函數(shù)文本,范圍內(nèi)沒有任何more的定義,編譯器會(huì)報(bào)錯(cuò)說:

 
 
 
  1. scala> (x: Int) => x + more  
  2. < console>:5: error: not found: value more  
  3.  (x: Int) => x + more  
  4.  ?  

另一方面,只要有一個(gè)叫做more的什么東西同樣的函數(shù)文本將工作正常:

 
 
 
  1. scala> var more = 1 
  2. more: Int = 1 
  3. scala> val addMore = (x: Int) => x + more  
  4. addMore: (Int) => Int = < function>  
  5. scala> addMore(10)  
  6. res19: Int = 11 

依照這個(gè)函數(shù)文本在運(yùn)行時(shí)創(chuàng)建的函數(shù)值(對(duì)象)被稱為
閉包:closure。名稱源自于通過“捕獲”自由變量的綁定對(duì)函數(shù)文本執(zhí)行的“關(guān)閉”行動(dòng)。不帶自由變量的函數(shù)文本,如(x: Int) => x + 1,被稱為
封閉術(shù)語:closed term,這里
術(shù)語:term指的是一小部分源代碼。因此依照這個(gè)函數(shù)文本在運(yùn)行時(shí)創(chuàng)建的函數(shù)值嚴(yán)格意義上來講就不是閉包,因?yàn)?x: Int) => x + 1在編寫的時(shí)候就已經(jīng)封閉了。但任何帶有自由變量的函數(shù)文本,如(x: Int) => x + more,都是
開放術(shù)語:open term。因此,任何依照(x: Int) => x + more在運(yùn)行期創(chuàng)建的函數(shù)值將必須捕獲它的自由變量,more,的綁定。由于函數(shù)值是關(guān)閉這個(gè)開放術(shù)語(x: Int) => x + more的行動(dòng)的最終產(chǎn)物,得到的函數(shù)值將包含一個(gè)指向捕獲的more變量的參考,因此被稱為閉包。

這個(gè)例子帶來一個(gè)問題:如果more在閉包創(chuàng)建之后被改變了會(huì)發(fā)生什么事?Scala里,答案是閉包看到了這個(gè)變化。如下:

 
 
 
  1. scala> more = 9999 
  2. more: Int = 9999 
  3. scala> addMore(10)  
  4. res21: Int = 10009 

直覺上,Scala的閉包捕獲了變量本身,而不是變量指向的值。
相對(duì)的,Java的內(nèi)部類根本不允許你訪問外圍范圍內(nèi)可以改變的變量,因此到底是捕獲了變量還是捕獲了它當(dāng)前具有的值就沒有差別了。就像前面演示的例子,依照(x: Int) => x + more創(chuàng)建的閉包看到了閉包之外做出的對(duì)more的變化。反過來也同樣。閉包對(duì)捕獲變量作出的改變?cè)陂]包之外也可見。下面是一個(gè)例子:

 
 
 
  1. scala> val someNumbers = List(-11, -10, -5, 0, 5, 10)  
  2. someNumbers: List[Int] = List(-11, -10, -5, 0, 5, 10)  
  3. scala> var sum = 0 
  4. sum: Int = 0 
  5. scala> someNumbers.foreach(sum += _)  
  6. scala> sum  
  7. res23: Int = -11 

例子用了一個(gè)循環(huán)的方式計(jì)算List的累加和。變量sum處于函數(shù)文本sum += _的外圍,函數(shù)文本把數(shù)累加到sum上。盡管這是一個(gè)在運(yùn)行期改變sum的閉包,作為結(jié)果的累加值,-11,仍然在閉包之外可見。

如果閉包訪問了某些在程序運(yùn)行時(shí)有若干不同備份的變量會(huì)怎樣?例如,如果閉包使用了某個(gè)函數(shù)的本地變量,并且函數(shù)被調(diào)用很多次會(huì)怎樣?每一次訪問使用的是變量的哪個(gè)實(shí)例?

僅有一個(gè)答案與語言余下的部分共存:使用的實(shí)例是那個(gè)在閉包被創(chuàng)建的時(shí)候活躍的。例如,以下是創(chuàng)建和返回“遞增”閉包的函數(shù):

 
 
 
  1. def makeIncreaser(more: Int) = (x: Int) => x + more  

每次函數(shù)被調(diào)用時(shí)都會(huì)創(chuàng)建一個(gè)新閉包。每個(gè)閉包都會(huì)訪問閉包創(chuàng)建時(shí)活躍的more變量。

 
 
 
  1. scala> val inc1 = makeIncreaser(1)  
  2. inc1: (Int) => Int = < function>  
  3. scala> val inc9999 = makeIncreaser(9999)  
  4. inc9999: (Int) => Int = < function>  

調(diào)用makeIncreaser(1)時(shí),捕獲值1當(dāng)作more的綁定的閉包被創(chuàng)建并返回。相似地,調(diào)用makeIncreaser(9999),捕獲值9999當(dāng)作more的閉包被返回。當(dāng)你把這些閉包應(yīng)用到參數(shù)上(本例中,只有一個(gè)參數(shù),x,必須被傳入),回來的結(jié)果依賴于閉包被創(chuàng)建時(shí)more是如何定義的:

 
 
 
  1. scala> inc1(10)  
  2. res24: Int = 11 
  3. scala> inc9999(10)  
  4. res25: Int = 10009 

盡管本例中more是一個(gè)已經(jīng)返回的方法調(diào)用的參數(shù)也沒有區(qū)別。Scala編譯器在這種情況下重新安排了它以使得捕獲的參數(shù)繼續(xù)存在于堆中,而不是堆棧中,因此可以保留在創(chuàng)建它的方法調(diào)用之外。這種重新安排的工作都是自動(dòng)關(guān)照的,因此你不需要操心。請(qǐng)任意捕獲你想要的變量:val,var,或參數(shù)。

【相關(guān)閱讀】

  1. Scala的偏應(yīng)用函數(shù)
  2. Scala:函數(shù)文本的短格式和占位符語法
  3. 介紹Scala的***類函數(shù)
  4. Scala的本地函數(shù):將私有方法轉(zhuǎn)換為本地方法
  5. Scala中定義函數(shù)的方法:method


網(wǎng)站名稱:學(xué)習(xí)Scala的閉包
當(dāng)前URL:http://uogjgqi.cn/article/copeecg.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流