Scala_方法和函數

方法的定義

def functionName([參數列表]) : [return type] = {
  function body
  return []
}
  • 若是沒有=和{}包裹的方法體,那麼該方法被隱式申明爲抽象(abstract)方法,包含它的類就是抽象類。
abstract class Test{
  def hi(x : Int):Int
  def he(x : Int){x + 1}
}
  • 當輸入相同類型的參數個數沒法肯定時,可使用變長參數,如:def sum(args : Int*) = {for(arg <- args) println(arg)}。
  • 若是方法體直接包裹在了花括號裏面,而沒有使用=鏈接,則方法的返回值就是(),其類型就是Unit,這樣的方法就被稱之爲過程。能夠爲過程指定返回值類型爲Unit,此時方法體中有return語句,方法返回值任然是Unit。

  • 不寫明返回值的類型,程序會自行判斷,最後一行代碼的執行結果爲返回值。

 

函數

Scala 方法是類的一部分,而函數是一個對象能夠賦值給一個變量。閉包

Scala 中的函數則是一個完整的對象,Scala 中的函數其實就是繼承了 Trait 的類的對象。函數

Scala 中使用 val 語句能夠定義函數,def 語句定義方法。優化

定義方式

1 class Test1{
2   def met(x : Int) = x + 10
3   val fun = (x : Int) => x + 10  // 匿名函數 (x : Int) => x + 10 賦值給變量 fun
4 }
  • 方法是一個以def開頭的帶有參數列表(能夠無參數列表)的一個邏輯操做塊,這正如object或者class中的成員方法同樣。
  • 函數是一個賦值給一個變量(或者常量)的匿名方法(帶或者不帶參數列表),而且經過=>轉換符號跟上邏輯代碼塊的一個表達式。=>轉換符號後面的邏輯代碼塊的寫法與method的body部分相同。

  • 方法名意味着方法調用,函數名只是表明函數自身。
  • 方法能夠沒有參數列表頁能夠是空的參數列表。
  • 函數必須設置參數列表,能夠是空的參數列表,但必定要設置。

方法和函數的相互轉換

  • 把 x => func(x) 簡化爲 func _ 或 func(_) 的過程稱爲函數轉換成方法

  • 把 func(_)或 func _ 展開爲 x => func(x) 的過程爲方法轉換成函數

 遞歸函數優化

正常遞歸函數會建立多個棧致使棧溢出,優化後不會建立新的棧,會使用前個函數的棧空間ui

經過註解優化遞歸函數(@annotation.tailrec),優化條件是最後一個語句是遞歸調用的函數,不然報錯spa

def dgui(n: Int,x:Int): Int = {
  if( x >= 1 ) n * dgui(n,x-1)
  else 1
}

@annotation.tailrec
def dguiTailrec(n: BigInt, acc: BigInt): BigInt = {
    if(n <= 1) acc
    else dguiTailrec(n-1, acc * n)
}

 高階函數

高階函數就是使用其餘函數做爲函數的參數,或者使用其餘函數做爲函數的輸出結果3d

test方法有兩個參數,第一個參數是名爲func的一個函數,該函數有一個String類型的參數,而且其返回值是Unit;第二個參數是String類型的contcode

test的方法體是將第二個參數cont做爲第一個參數即函數func的參數;test方法的返回值是Unit對象

Scala 函數柯里化(Currying)

柯里化指的是將原來接受兩個參數的函數變成新的接受一個參數的函數的過程。新的函數返回一個以原有第二個參數爲參數的函數。blog

def add(x:Int,y:Int)=x+y

柯里化

def add(x:Int)(y:Int) = x + y

函數的currying化行爲本質上也是一個高階函數:接受現有的函數,返回新函數。
這個例子就是對上一個例子的currying化操做。傳入第一個參數後返回一個函數,而後再傳入第二個參數,完成第二個函數。這樣就講一個高階函數拆解成兩個一階函數。繼承

閉包

閉包是一個函數,返回值依賴於聲明在函數外部的一個或多個變量。

var factor = 3  
val multiplier = (i:Int) => i * factor  
相關文章
相關標籤/搜索