現在的位置: 首頁 > 編程語言 > 正文

為什麼使用Lambda表達式?Scala中的Lambda表達式是什麼

2020年06月05日 編程語言 ⁄ 共 2906字 ⁄ 字型大小 評論關閉

  Java8終於要支持Lambda表達式!自2009年以來Lambda表達式已經在Lambda項目中被支持。在那時候,Lambda表達式仍被稱為Java閉包。下面學步園小編來講解下為什麼使用Lambda表達式?Scala中的Lambda表達式是什麼?

  為什麼使用Lambda表達式

  Lambda表達式通常使用在圖形用戶界面(GUI)的開發中。一般來說,GUI編程將程序行為和事件做連接。比如,當用戶按下一個按鈕(觸發一個事件),你的程序就需要去執行某些行為,可能是將一些數據儲存到一個數據存儲器中。在Swing中,可以使用ActionListener來實現:

  classButtonHandlerimplementsActionListener{

  publicvoidactionPerformed(ActionEvente)

  {

  //dosomething

  }

  }

  classUIBuilder{

  publicUIBuilder(){

  button.addActionListener(newButtonHandler());

  }

  }

  這個例子表明了ButtonHandler類作為一個回調替換的用法。在這裡ButtonHandler類僅包含ActionListener介面定義的actionPerformed方法。我們可以使用匿名內部類來簡化代碼:

  classUIBuilder{

  publicUIBuilder(){

  button.addActionListener(newActionListener(){

  publicvoidactionPerformed(ActionEventevent){

  //dosomething

  }

  })

  }

  }

  這樣代碼簡潔多了。更仔細的去看代碼時,就會發現我們還創建一個只生成一個實例的類,而這個實例也僅僅持有一個獨立的方法。這恰好是Lambda表達式所能解決的其中一類問題。

  Lambda表達式代替函數

  一個lambda表達式從字面上講就是一個函數。它定義了一個函數的輸入參數和函數體。Java8中的,lambda表達式語法尚未確定,不過大致應該類似這個樣子的:

  (typeparameter)->function_body一個具體的例子:

  (Strings1,Strings2)->s1.length()-s2.length();

  這個lambda表達式用來計算兩個字元串的長度差。還有一些擴展的語法,比如避免參數的類型定義(我們馬上見看到例子)還有使用{和}來支持多行定義。

  Collections.sort()

  方法是lambda表達的理想例子。它允許我們將字元串按照長度排序:

  Listlist=Array.asList("loooooong","short","tiny");

  Collections.sort(list,(Strings1,Strings2)->s1.length()-s2.length());

  >"tiny","short","loooooong".

  所以,不像現在java必須要求的向sort方法輸入一個已經實現的Comparator(比較器)而是傳送一個lambda表達式我們就可以得到相同的結果。

  Lambda表達式代替閉包

  lambda表達式有許多有趣的特性。其中之一是,它們是閉包。一個閉包允許函數訪問直接詞法作用域之外的變數。

  Stringouter="java8"(Strings1)->s1.length()-outer.length()

  在例子中,lambda表達式訪問了字元串outer這個作用域之外定義的變數。對於內聯閉包來說這是很難做到的。

  Lambda表達式也支持類型推論

  類型推論是java7引入的但它同樣適用於lambda表達式。簡單來說,類型推論意味著程序員可以在任意一個編譯器能夠自動推斷出類型的地方省略類型定義。如果類型推論能夠應用到前面的排序lambda表達式上,那麼它就能寫成下面的樣子:

  Listlist=Arrays.asList(…);

  Collections.sort(list,(s1,s2)->s1.length()-s2.length());

  就像你所見到的一樣,參數s1和s2的類型被省略了。因為編譯器知道list是一個字元串集合,它知道被用來作為比較器的lambda表達式必定是相同的類型。因此,這個類型不需要顯式地聲明,即使你有這麼做的自由。

  類型推論的主要優勢就是減少樣板代碼,如果編譯器可以為我們識別類型,為什麼我們必須自己定義它們。

  珍愛Lambda表達式,遠離匿名內部類

  我們來體會下,為何lambda表達式和類型推論有助於簡化我們前面所提到的回調例子:

  classUIBuilder{

  publicUIBuilder(){

  button.addActionListener(e->//processActionEvente)

  }

  }

  我們下載直接傳送一個lambda表達式進入addActionListener方法來代替前面定義的持有回調方法的類。除了減少模板代碼和提高可讀性以外,它使我們直接表達我們唯一感興趣的事情:處理事件。

  在我們了解lambda表達式更多優勢之前,先來看看在Scala中的lambda表達式副本。

  Scala中的Lambda表達式是什麼

  在函數式編程中,函數是基本的構造塊。Scala融合了java中的面向對象編程和函數式編程。在Scala中,一個lambda表達式是種叫做"函數"或者"函數文本".Scala中的函數屬於一等公民。它們可以被分配給vals或者vars(最終變數或者非最終變數),它們可以作為其他函數的參數,也可以組合成新的函數。

  在Scala中一個函數文本寫成如下形式:

  (argument)=>//funtionbody

  舉例來說,前面提到的java用來計算兩個字元串長度差的lambda表達式,在Scala中寫作如下:

  (s1:String,s2:String)=>s1.length-s2.

  lengthScala中的函數文本也是閉包。它可以訪問在直接詞法作用域之外定義的變數。

  valouter=10valmyFuncLiteral=(y:Int)=>y*outervalresult=myFuncLiteral(2)>20這個例子結果是20.

  正如你所見,我們將函數文本分配給了變數myFuncLiteral.

  java8的lambda表達式和Scala的函數文本在語法和語義上的相似性是十分明顯的。從語義上講它們是相同的,而語法上的唯一不同就是箭頭符號(java8->,scala=>)和我們沒有提到的簡化符號。

  以上就是關於「為什麼使用Lambda表達式?Scala中的Lambda表達式是什麼」的內容,希望對大家有用。更多資訊請關注學步園。學步園,您學習IT技術的優質平台!

抱歉!評論已關閉.