函數的類型和值
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