日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Scala的偏應(yīng)用函數(shù)

盡管前面的例子里下劃線替代的只是單個(gè)參數(shù),你還可以使用一個(gè)下劃線替換整個(gè)參數(shù)列表。例如,寫成println(_),或者更好的方法你還可以寫成println _。下面是一個(gè)例子:

10年積累的網(wǎng)站設(shè)計(jì)制作、做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有鞏留免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

 
 
 
  1. someNumbers.foreach(println _)  

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

Scala把這種短格式直接看作是你輸入了下列代碼:

 
 
 
  1. someNumbers.foreach(x => println(x)) 

因此,這個(gè)例子中的下劃線不是單個(gè)參數(shù)的占位符。它是整個(gè)參數(shù)列表的占位符。請(qǐng)記住要在函數(shù)名和下劃線之間留一個(gè)空格,因?yàn)椴贿@樣做編譯器會(huì)認(rèn)為你是在說明一個(gè)不同的符號(hào),比方說是,似乎不存在的名為println_的方法。

以這種方式使用下劃線時(shí),你就正在寫一個(gè)偏應(yīng)用函數(shù):partially applied function。Scala里,當(dāng)你調(diào)用函數(shù),傳入任何需要的參數(shù),你就是在把函數(shù)應(yīng)用到參數(shù)上。如,給定下列函數(shù):

 
 
 
  1. scala> def sum(a: Int, b: Int, c: Int) = a + b + c  
  2. sum: (Int,Int,Int)Int  

你就可以把函數(shù)sum應(yīng)用到參數(shù)1,2和3上,如下:

 
 
 
  1. scala> sum(1, 2, 3)  
  2. res12: Int = 6 

偏應(yīng)用函數(shù)是一種表達(dá)式,你不需要提供函數(shù)需要的所有參數(shù)。代之以僅提供部分,或不提供所需參數(shù)。比如,要?jiǎng)?chuàng)建不提供任何三個(gè)所需參數(shù)的調(diào)用sum的偏應(yīng)用表達(dá)式,只要在“sum”之后放一個(gè)下劃線即可。然后可以把得到的函數(shù)存入變量。舉例如下:

 
 
 
  1. scala> val a = sum _  
  2. a: (Int, Int, Int) => Int = < function>  

有了這個(gè)代碼,Scala編譯器以偏應(yīng)用函數(shù)表達(dá)式,sum _,實(shí)例化一個(gè)帶三個(gè)缺失整數(shù)參數(shù)的函數(shù)值,并把這個(gè)新的函數(shù)值的索引賦給變量a。當(dāng)你把這個(gè)新函數(shù)值應(yīng)用于三個(gè)參數(shù)之上時(shí),它就轉(zhuǎn)回頭調(diào)用sum,并傳入這三個(gè)參數(shù):

 
 
 
  1. scala> a(1, 2, 3)  
  2. res13: Int = 6 

實(shí)際發(fā)生的事情是這樣的:名為a的變量指向一個(gè)函數(shù)值對(duì)象。這個(gè)函數(shù)值是由Scala編譯器依照偏應(yīng)用函數(shù)表達(dá)式sum _,自動(dòng)產(chǎn)生的類的一個(gè)實(shí)例。編譯器產(chǎn)生的類有一個(gè)apply方法帶三個(gè)參數(shù)。
產(chǎn)生的類擴(kuò)展了特質(zhì)Function3,定義了三個(gè)參數(shù)的apply方法。之所以帶三個(gè)參數(shù)是因?yàn)閟um _表達(dá)式缺少的參數(shù)數(shù)量為三。Scala編譯器把表達(dá)式a(1,2,3)翻譯成對(duì)函數(shù)值的apply方法的調(diào)用,傳入三個(gè)參數(shù)1,2,3。因此a(1,2,3)是下列代碼的短格式:

 
 
 
  1. scala> a.apply(1, 2, 3)  
  2. res14: Int = 6 

Scala編譯器根據(jù)表達(dá)式sum _自動(dòng)產(chǎn)生的類里的apply方法,簡(jiǎn)單地把這三個(gè)缺失的參數(shù)前轉(zhuǎn)到sum,并返回結(jié)果。本例中apply調(diào)用了sum(1,2,3),并返回sum返回的,6。

這種一個(gè)下劃線代表全部參數(shù)列表的表達(dá)式的另一種用途,就是把它當(dāng)作轉(zhuǎn)換def為函數(shù)值的方式。例如,如果你有一個(gè)本地函數(shù),如sum(a: Int, b: Int, c: Int): Int,你可以把它“包裝”在apply方法具有同樣的參數(shù)列表和結(jié)果類型的函數(shù)值中。當(dāng)你把這個(gè)函數(shù)值應(yīng)用到某些參數(shù)上時(shí),它依次把sum應(yīng)用到同樣的參數(shù),并返回結(jié)果。盡管不能把方法或嵌套函數(shù)賦值給變量,或當(dāng)作參數(shù)傳遞給其它方法,但是如果你把方法或嵌套函數(shù)通過在名稱后面加一個(gè)下劃線的方式包裝在函數(shù)值中,就可以做到了。

現(xiàn)在,盡管sum _確實(shí)是一個(gè)偏應(yīng)用函數(shù),或許對(duì)你來說為什么這么稱呼并不是很明顯。這個(gè)名字源自于函數(shù)未被應(yīng)用于它所有的參數(shù)。在sum _的例子里,它沒有應(yīng)用于任何參數(shù)。不過還可以通過提供某些但不是全部需要的參數(shù)表達(dá)一個(gè)偏應(yīng)用函數(shù)。舉例如下:

 
 
 
  1. scala> val b = sum(1, _: Int, 3)  
  2. b: (Int) => Int = < function> 

這個(gè)例子里,你提供了***個(gè)和***一個(gè)參數(shù)給sum,但中間參數(shù)缺失。因?yàn)閮H有一個(gè)參數(shù)缺失,Scala編譯器會(huì)產(chǎn)生一個(gè)新的函數(shù)類,其apply方法帶一個(gè)參數(shù)。在使用一個(gè)參數(shù)調(diào)用的時(shí)候,這個(gè)產(chǎn)生的函數(shù)的apply方法調(diào)用sum,傳入1,傳遞給函數(shù)的參數(shù),還有3。如下:

 
 
 
  1. scala> b(2)  
  2. res15: Int = 6 

這個(gè)例子里,b.apply調(diào)用了sum(1,2,3)。

 
 
 
  1. scala> b(5)  
  2. res16: Int = 9 

這個(gè)例子里,b.apply調(diào)用了sum(1,5,3)。

如果你正在寫一個(gè)省略所有參數(shù)的偏應(yīng)用程序表達(dá)式,如println _或sum _,而且在代碼的那個(gè)地方正需要一個(gè)函數(shù),你可以去掉下劃線從而表達(dá)得更簡(jiǎn)明。例如,代之以打印輸出someNumbers里的每一個(gè)數(shù)字(定義在第113頁)的這種寫法:

 
 
 
  1. someNumbers.foreach(println _)  

你可以只是寫成:

 
 
 
  1. someNumbers.foreach(println)  

***一種格式僅在需要寫函數(shù)的地方,如例子中的foreach調(diào)用,才能使用。編譯器知道這種情況需要一個(gè)函數(shù),因?yàn)閒oreach需要一個(gè)函數(shù)作為參數(shù)傳入。在不需要函數(shù)的情況下,嘗試使用這種格式將引發(fā)一個(gè)編譯錯(cuò)誤。舉例如下:

 
 
 
  1. scala> val c = sum  
  2. < console>:5: error: missing arguments for method sum...  
  3. follow this method with `_' if you want to treat it as  
  4.  a partially applied function  
  5.  val c = sum  
  6.  ?  
  7. scala> val d = sum _  
  8. d: (Int, Int, Int) => Int = < function>  
  9. scala> d(10, 20, 30)  
  10. res17: Int = 60 

為什么要使用尾下劃線?

Scala的偏應(yīng)用函數(shù)語法凸顯了Scala與經(jīng)典函數(shù)式語言如Haskell或ML之間,設(shè)計(jì)折中的差異。在經(jīng)典函數(shù)式語言中,偏應(yīng)用函數(shù)被當(dāng)作普通的例子。更進(jìn)一步,這些語言擁有非常嚴(yán)格的靜態(tài)類型系統(tǒng)能夠暴露出你在偏應(yīng)用中可能犯的所有錯(cuò)誤。Scala與指令式語言如Java關(guān)系近得多,在這些語言中沒有應(yīng)用所有參數(shù)的方法會(huì)被認(rèn)為是錯(cuò)誤的。進(jìn)一步說,子類型推斷的面向?qū)ο蟮膫鹘y(tǒng)和全局的根類型接受一些被經(jīng)典函數(shù)式語言認(rèn)為是錯(cuò)誤的程序。

舉例來說,如果你誤以為L(zhǎng)ist的drop(n: Int)方法如tail(),那么你會(huì)忘記你需要傳遞給drop一個(gè)數(shù)字。你或許會(huì)寫,“println(drop)”。如果Scala采用偏應(yīng)用函數(shù)在哪兒都OK的經(jīng)典函數(shù)式傳統(tǒng),這個(gè)代碼就將通過類型檢查。然而,你會(huì)驚奇地發(fā)現(xiàn)這個(gè)println語句打印的輸出將總是< function>!可能發(fā)生的事情是表達(dá)式drop將被看作是函數(shù)對(duì)象。因?yàn)閜rintln可以帶任何類型對(duì)象,這個(gè)代碼可以編譯通過,但產(chǎn)生出乎意料的結(jié)果。

為了避免這樣的情況,Scala需要你指定顯示省略的函數(shù)參數(shù),盡管標(biāo)志簡(jiǎn)單到僅用一個(gè)‘_’。Scala允許你僅在需要函數(shù)類型的地方才能省略這個(gè)僅用的_。

【相關(guān)閱讀】

  1. Scala:函數(shù)文本的短格式和占位符語法
  2. 介紹Scala的***類函數(shù)
  3. Scala的本地函數(shù):將私有方法轉(zhuǎn)換為本地方法
  4. Scala中定義函數(shù)的方法:method
  5. 繼續(xù)領(lǐng)悟函數(shù)式:Scala指令式風(fēng)格代碼的重構(gòu)

新聞名稱:Scala的偏應(yīng)用函數(shù)
分享鏈接:http://m.5511xx.com/article/cdiedce.html