Scala的匿名函數!

有這樣一個函數, 它接受一個函數(或者說閉包   此處說是閉包有點勉強,因爲接受函數作爲參數的函數應稱之爲高階函數而不是閉包)作爲參數:

object Timer{
  def oncePerSecond(callback: () => unit): unit = {
    while (true){
      callback()
      Thread.sleep(1000)
    }
  }

  def timeFlies(): unit = { 
    Console.println("Time flies when you're having fun(ctionally)...");
  }

  def main(args: Array[String]): unit = {
    oncePerSecond(timeFlies)
  }
}

觀察函數oncePerSecond, 它的參數callback被定義爲" () => unit", 表示callback接受一個函數, 並且這個函數
    1. 不能帶參數; 因爲"()"

    2. 返回值的類型爲unit, 即沒有返回值; 因爲" => unit", "=>" 表示返回值, "unit"表示返回值的類型,這是作爲參數聲明,使用的是=>,如果是函數定義無返回值則使用 :


再觀察函數timeFlies, 它滿足以上兩個條件, 因此, 可以這麼調用: oncePerSecond(timeFlies)




匿名函數

更進一步, 我們可以不用聲明函數timeFiles, 而直接將它的主體作爲參數傳遞給oncePerSecond:

  def timeFlies(): unit = { 
    Console.println("Time flies when you're having fun(ctionally)...");
  }

  進一步簡化爲匿名函數, 或者說是閉包, 或者說是code block  此處有誤,匿名函數可不是閉包:

  () => Console.println("Time flies when you're having fun(ctionally)..."


  調用匿名函數:

  oncePerSecond(() => Console.println("Time flies... oh, you get the idea."))




更典型的例子


觀察下面的scala代碼:

object HelloWorld{
  def main(args: Array[String]): unit = {
    args.filter( (arg:String) => arg.startsWith("G") )
        .foreach( (arg:String) => Console.println("Found " + arg) )
  }
}


1. 函數main的參數是Array類型的String數組 args: Array[String]
2. Scala數組有一個方法filter, 方法filter(b)返回一個符合某個條件b的數組
   
    args.filter( (arg:String) => arg.startsWith("G") )

   和上面的匿名函數一樣, 紅色部分也是一個匿名函數, 不同的是, 該函數接受一個String值,並且返回一個boolean值:
    
    (arg:String) => arg.startsWith("G") 

    在args.filter()函數的圓括號內, arg:String 表示枚舉args中的每一個值. arg.startsWith("G")是Java的String類型的函數, 因此, 這個匿名函數的含義是:
    從args中, 返回一個字符串數組, 並且這個字符串數組的字符串,都是以字符"G"開頭的.

   和args.filter()一樣, foreach也是Scala數組的一個方法. 
發佈了12 篇原創文章 · 獲贊 28 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章