1. 程式人生 > >Scala 方法與函式

Scala 方法與函式

Scala 方法與函式:http://www.runoob.com/scala/scala-functions.html

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

Scala 中的方法跟 Java 的類似,方法是組成類的一部分。

Scala 中的函式則是一個完整的物件,Scala 中的函式其實就是繼承了 Trait 的類的物件。

Scala 中使用 val 語句可以定義函式,def 語句定義方法。

class Test{
  def m(x: Int) = x + 3 val f = (x: Int) => x + 3 }

注意:有些翻譯上函式(function)與方法(method)是沒有區別的。


方法宣告

Scala 方法宣告格式如下:

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

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


方法定義

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

Scala 方法定義格式如下:

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

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

以下方法的功能是將兩個傳入的引數相加並求和:

object add{
   def addInt( a:Int, b:Int ) : Int = { var sum:Int = 0 sum = a + b return sum } }

如果方法沒有返回值,可以返回為 Unit,這個類似於 Java 的 void, 例項如下:

object Hello{
   def printMe( ) : Unit = { println("Hello, Scala!") } }

方法呼叫

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

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

functionName( 引數列表 )

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

[instance.]functionName( 引數列表 )

以上例項演示了定義與呼叫方法的例項:

object Test { def main(args: Array[String]) { println( "Returned Value : " + addInt(5,7) ); } def addInt( a:Int, b:Int ) : Int = { var sum:Int = 0 sum = a + b return sum } }

執行以上程式碼,輸出結果為:

$ scalac Test.scala 
$ scala Test Returned Value : 12

 


//////////////////////////////////////////////////////////////

1、函式可作為一個引數傳入到方法中,而方法不行。

object MethodAndFunctionDemo { //定義一個方法 //方法 m1 引數要求是一個函式,函式的引數必須是兩個Int型別 //返回值型別也是Int型別 def m1(f:(Int,Int) => Int) : Int = { f(2,6) } //定義一個函式f1,引數是兩個Int型別,返回值是一個Int型別 val f1 = (x:Int,y:Int) => x + y //再定義一個函式f2 val f2 = (m:Int,n:Int) => m * n //main方法 def main(args: Array[String]): Unit = { //呼叫m1方法,並傳入f1函式 val r1 = m1(f1) println(r1) //呼叫m1方法,並傳入f2函式 val r2 = m1(f2) println(r2) } }

執行結果:

8
12

2、在Scala中無法直接操作方法,如果要操作方法,必須先將其轉換成函式。有兩種方法可以將方法轉換成函式:

val f1 = m _

在方法名稱m後面緊跟一個空格和下劃線告訴編譯器將方法m轉換成函式,而不是要呼叫這個方法。 也可以顯示地告訴編譯器需要將方法轉換成函式:

val f1: (Int) => Int = m

通常情況下編譯器會自動將方法轉換成函式,例如在一個應該傳入函式引數的地方傳入了一個方法,編譯器會自動將傳入的方法轉換成函式。

object TestMap { def ttt(f:Int => Int):Unit = { val r = f(10) println(r) } val f0 = (x : Int) => x * x //定義了一個方法 def m0(x:Int) : Int = { //傳遞進來的引數乘以10 x * 10 } //將方法轉換成函式,利用了神奇的下滑線 val f1 = m0 _ def main(args: Array[String]): Unit = { ttt(f0) //通過m0 _將方法轉化成函式 ttt(m0 _); //如果直接傳遞的是方法名稱,scala相當於是把方法轉成了函式 ttt(m0) //通過x => m0(x)的方式將方法轉化成函式,這個函式是一個匿名函式,等價:(x:Int) => m0(x) ttt(x => m0(x)) } }

輸出結果為:

100
100
100 100

3、函式必須要有引數列表,而方法可以沒有引數列表

4、在函數出現的地方我們可以提供一個方法

在需要函式的地方,如果傳遞一個方法,會自動進行ETA展開(把方法轉換為函式)

如果我們直接把一個方法賦值給變數會報錯。如果我們指定變數的型別就是函式,那麼就可以通過編譯,如下:

當然我們也可以強制把一個方法轉換給函式,這就用到了 scala 中的部分應用函式: