1. 程式人生 > >Scala學習筆記之方法與函式

Scala學習筆記之方法與函式

Scala裡有方法和函式,第一感覺兩者應該沒啥區別吧,其實不然,Scala方法是類的一部分,而函式是一個物件,可以賦值給一個變數,換言之,在類中的函式就是方法。

Scala裡可以用 val 定義函式,用 def 定義方法

class Test {
	def method1(a: Int, b:Int) = {
		return a+b
	}
	val f = (x:Int) => x+3
}

方法的定義

Scala方法定義格式如下:

def functionName([引數列表]):返回型別 = {
	function body
	return expr
}

我們看一個例子

object add {
  def main(args: Array[String]) {
    println("method addInt: ", addInt(2,4))
    printMe()
  }

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

  def printMe():Unit = {
    println("printMe")
  }

}

執行結果如下:

(method addInt: ,6)
printMe

函式傳名呼叫

scala的直譯器在解析函式呼叫引數時有兩種方式

  • 傳值呼叫(call-by-value):先計算引數表示式的值,再應用到函式內部
  • 傳名呼叫(call-by-name):將未計算的引數表示式直接應用到函式內部

我們看一個例子:

object Test {
   def main(args: Array[String]) {
        timeDelayed(getTime());
   }

   def getTime() = {
      println("獲取時間,單位為納秒")
      System.nanoTime
   }
def timeDelayed( t: => Long ) = { println("在 delayed 方法內") println("引數: " + t) t } }

執行結果如下:

在timeDelayed方法內
獲取時間,單位是納秒
(引數: 21847264195735)
獲取時間,單位是納秒

這裡很神奇,為啥會輸出兩條 “獲取時間,單位是納秒”。其實是因為我們在timeDelayed方法裡設定了傳名呼叫,就是在引數和變數型別直接加了一個 “=>”,因此在執行 timeDelayed(getTime()) 時,首先執行timeDelayed()方法裡第一個輸出,表示進入了該方法,接著列印接收到的引數值,最後再返回 t

指定函式引數名

一般情況下,函式呼叫引數會按照定義時的順序一個一個呼叫,Scala裡也可以指定函式引數名,不用按照引數順序傳遞。

object Test {
   def main(args: Array[String]) {
        printInt(b=5, a=7);
   }
   def printInt( a:Int, b:Int ) = {
      println("Value of a : " + a );
      println("Value of b : " + b );
   }
}

執行結果:

Value of a : 7
Value of b : a

可變引數

Scala 允許我們不用指定引數個數,傳入可變長度的引數列表。通過在引數的型別後面加一個星號

object Test {
   def main(args: Array[String]) {
        printStrings("python", "Scala", "ruby");
   }
   def printStrings( args:String* ) = {
      var i : Int = 0
      for( arg <- args ){
         println("Arg value[" + i + "] = " + arg )
         i = i + 1
      }
   }
}

執行結果:

Arg value[0] = python
Arg value[1] = Scala
Arg value[2] = ruby

遞迴函式

遞迴函式在程式設計裡起到非常重要的作用,我們以計算階乘為例。

object Test {
   def main(args: Array[String]) {
      for (i <- 1 to 10)
         println(i + " 的階乘為: " + factorial(i) )
   }
   
   def factorial(n: BigInt): BigInt = {  
      if (n <= 1)
         1  
      else    
      n * factorial(n - 1)
   }
}

執行結果:

1 的階乘是: 1
2 的階乘是: 2
3 的階乘是: 6
4 的階乘是: 24
5 的階乘是: 120
6 的階乘是: 720
7 的階乘是: 5040
8 的階乘是: 40320
9 的階乘是: 362880
10 的階乘是: 3628800