1. 程式人生 > >Scala:函式和閉包

Scala:函式和閉包

Scala函式

Scala 有函式和方法,二者在語義上的區別很小。Scala 方法是類的一部分,而函式是一個物件可以賦值給一個變數。換句話來說在類中定義的函式即是方法。

我們可以在任何地方定義函式,甚至可以在函式內定義函式(內嵌函式)。更重要的一點是 Scala 函式名可以由以下特殊字元:+, ++, ~, &,-, -- , \, /, : 等。

函式宣告和定義

Scala 函式宣告格式如下:

def functionName ([引數列表]):[return type]

如果你不寫等於號和方法主體,那麼方法會被隱式宣告為"抽象(abstract)",包含它的型別於是也是一個抽象型別。

方法定義由一個def 關鍵字開始,緊接著是可選的引數列表,一個冒號":" 和方法的返回型別,一個等於號"=",最後是方法的主體。

Scala 函式定義格式如下:

def functionName ([引數列表]):[return type]={function body
   return[expr]}

以上程式碼中 return type 可以是任意合法的 Scala 資料型別。引數列表中的引數可以使用逗號分隔。

函式返回值

在scala中,語句塊的最後一個值就是這個語句塊的值,因此函式並不使用return來返回值,而是簡單的把結果放到最後一條語句。

如def getK: Int = k

函式呼叫

Scala 提供了多種不同的函式呼叫方式:

以下是呼叫方法的標準格式:

functionName(引數列表)

如果函式使用了例項的物件來呼叫,我們可以使用類似java的格式 (使用 .

號):

[instance.]functionName(引數列表)

Scala通用函式

map
map接受一個處理單個元素的函式,map把這個函式運用在列表的每個元素上放回一個一樣長的列表
filter
filter接受一個返回boolean的的值,filter會取出得到true的元素,返回過濾過的列表
foreach
類似於map
mkString
相當於toString,但是需要一個分隔符
zip
zip把兩個列表的元素依次結合得到一個元祖集合
reduce
reduceLeft接受一個接受兩個引數的函式,reduceLeft會依次把前一次得到的結果和下一個列表元素傳遞給函式,最後得到一個單個元素
fold
foldLeft和foldRight接受一個需要兩個引數的函式,並且依層呼叫如(1::2::3).foldLeft(1)(_*_)=6
以層次話的方式求值

函式概念解析接案例

[http://www.runoob.com]

Scala 閉包

閉包是一個函式,返回值依賴於宣告在函式外部的一個或多個變數。

閉包通常來講可以簡單的認為是可以訪問一個函式裡面區域性變數的另外一個函式。

如下面這段匿名的函式:

val multiplier =(i:Int)=> i *10

函式體內有一個變數 i,它作為函式的一個引數。如下面的另一段程式碼:

val multiplier =(i:Int)=> i * factor

在 multiplier 中有兩個變數:i 和 factor。其中的一個 i 是函式的形式引數,在 multiplier 函式被呼叫時,i 被賦予一個新的值。然而,factor不是形式引數,而是自由變數,考慮下面程式碼:

var factor =3  
val multiplier =(i:Int)=> i * factor  

這裡我們引入一個自由變數 factor,這個變數定義在函式外面。

這樣定義的函式變數 multiplier 成為一個"閉包",因為它引用到函式外面定義的變數,定義這個函式的過程是將這個自由變數捕獲而構成一個封閉的函式。