【scala】匿名函數和閉包


函數的類型和值

Scala是一種純面向對象的語言,每個值都是對象。Java是一種不全面向對象的語言。

Scala也是一種函數式語言,其函數也能當成值來使用。Java則是指令試編程。

但是Scala同時支持指令試編程和函數式編程,是兩種編程方式的結合的一門語言。

在Scala中,我們可以把函數當作一個數據類型,可以像任何其他數據類型一樣被傳遞和操作。這體現了函數式編程的核心。

我們可以像定義變量的那樣去定義一個函數,因此,函數也就會和其他變量一樣擁有類型和值。

我們看個例子

def counter( value:Int ) : Int = { value + 1 }

我們定義了一個counter函數,參數為Int類型的value,返回值為Int類型,大小為value+1。

counter函數的類型為  ( Int ) => Int 

箭頭前,圓括號里面的為參數的類型,有多個參數依次寫到圓括號中即可,(Int,String)。

當只有一個參數的時候可以省略圓括號 Int => Int

箭頭后,為返回值類型

counter函數的值為(value) => { value + 1}

箭頭前,圓括號里面的為參數的值,多個參數依次寫到圓括號中即可。我們可以在這里定義參數類型,(value:Int)=>{value+1}

箭頭后,大括號里面為返回的值,當只有一條語句的時候可以省略掉大括號。(value)=> value + 1

我們知道了函數的類型和值,試試定義一個函數變量。

val num : Int = 5;
//我們照着這個例子完成函數變量的定義
val counter :(Int)=> Int  = { (value) => {value+1} }

使用函數變量

println( counter(1) )

匿名函數

當一個函數就只用一次,我們就不需要給函數命名,這時我們就可以使用匿名函數。

我們通常把匿名函數稱為“Lambda表達式”。

格式如下:(參數) => 表達式       //如果參數只有一個,圓括號可以省略

示例

(num:Int) =>  num*2

我們可以直接把匿名函數放到變量中

val myNum :(Int) => Int = (num:Int) => num *2   
//這里的形式和上面定義函數變量是一樣的,只有一條語句的時候可以省略{}
//我們可以省略掉返回類型讓語言自己判斷,但是需要添加傳入參數的類型
val myNum = (num:Int) => num*2   
println(myNum(1))  //使用函數變量

我們需要注意,雖然Scala語言有自動推斷類型機制,但是我們不能全部省略,需要有部分類型確定才能推斷出省略的部分類型。

閉包

閉包是一個函數,返回值依賴於聲明在函數外部的一個或多個變量。

val myNum = (num:Int) => num*2  //普通函數
val myNum = (num:Int) => num*a  //閉包,a為變量

我們看到閉包和普通函數的區別,閉包函數的返回值不僅根據參數num來確定,還依賴於外部的變量a

我們不能在沒有定義變量a之前定義這個閉包,會提示not found value a。

正確定義閉包函數的方式

scala> var a = 10
a: Int = 10

scala> val myNum = (num:Int) => num*a   //定義閉包函數前依賴的變量必須有值
myNum: Int => Int = $$Lambda$1050/1792172929@4b20aa21

scala> myNum(10)
res2: Int = 100
scala> a = 20   //當我們修改外部的a的變量值,閉包函數的返回值也跟着變化,創建出一個新的閉包
a: Int = 20

scala> myNum(10)
res3: Int = 200

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM