1、求值策略
scala里有兩種求值策略
Call By Value -先對函數實參求值,在函數體中用這個求出的參數值。
Call By Name -先不對函數實參求值,而是函數實參每次在函數體內被用到時都會求值。
scala通常使用Call By Value
如果函數形參類型以 =>開頭,那么就是在使用Call By Name
def foo(x : Int)= x //Call By Value
def foo(x : => Int)= x //Call By Name
def loop():Int = loop //遞歸函數 //> loop: ()Int
def bar(x : Int,y : =>Int) =1 //> bar: (x: Int, y: => Int)Int
bar(1,loop) //> res3: Int = 1
//bar(loop,1) //會死循環
2、高階函數
用函數作為形參或帶返回值的函數,稱為高階函數
def operate(f: (Int,Int) => Int)={
f(4,4)
}//形參傳入的是一個函數
def greeting()= (name: String) =>{"hello "+name}//返回一個匿名函數
3、匿名函數
匿名函數就是函數常量,也稱為函數文字量
在scala里,匿名函數的定義格式為(形參列表)=>{函數體}
4、柯理化
柯理化函數把具有多個參數的函數轉換為一條函數鏈,每個節點上是單一參數
def add(x: Int,y: Int)= x + y //常規函數寫法
def add(x: Int)(y: Int) = x + y //scala中柯理化的語法
5、遞歸函數
在函數式編程中是實現循環的一種技術。
缺陷:遞歸的層數越深,棧就越多。
6、尾遞歸函數
尾遞歸函數中所有遞歸形式的調用都出現在函數的末尾。
當編譯器檢測到一個函數調用的是尾遞歸的時候,它就覆蓋當前的活動記錄而不是在棧中去創建一個新的。
def factorial(n: Int):Int = {
if(n<=0) 1
else n*factorial(n)
}
@annotation.tailrec
def factorial(n: Int,m: Int):Int = {
if(n<=0) m
else factorial(n-1,m*n)
}
-----------下面是scala中常用函數的使用------------
val multiplier = (i: Int, m: Int) => i * m //> multiplier : (Int, Int) => Int = <function2>
def function1(n: Int): Int = {
multiplier.apply(n, 2) //等價於multiplier(n,2)
} //> function1: (n: Int)Int
function1(1) //> res4: Int = 2
def function2(m: (Int) => Int) = m //> function2: (m: Int => Int)Int => Int
def funint2(m: Int): Int = m //> funint2: (m: Int)Int
function2(funint2)(2) //> res5: Int = 2
def function3(f: (Int, Int) => Int) = f //> function3: (f: (Int, Int) => Int)(Int, Int) => Int
def funint3(m: Int,n: Int): Int= m*n //> funint3: (m: Int, n: Int)Int
function3(funint3)(2,3) //> res6: Int = 6
def greeting()= (name: String) => {"hello "+ name}
//> greeting: ()String => String
greeting()("xiaoming") //> res7: String = hello xiaoming
val function4 = (x: Int) => x + 1 //> function4 : Int => Int = <function1>
function4(4) //>res8: Int = 5
val function5 = (x:Int) => {
if(x > 1){
"x>1 and x=" +x
}else{
"x<1 and x = " +x
}
} //> function5 : Int => String = <function1>
function5(5) //> res9: String = x>1 and x=5
val function6 = (_ : Int) + ( _ :Int) //> function6 : (Int, Int) => Int = <function2>
function6(5,6) //> res10: Int = 11
def function7(a:Int, b:Int, c:Int) = a+b+c //> function7: (a: Int, b: Int, c: Int)Int
val function8 = function7 _ //> function8 : (Int, Int, Int) => Int = <function3>
function8(1,2,3) //> res11: Int = 6
def function9(args: Int*) = for (arg <- args) println(arg)
//> function9: (args: Int*)Unit
function9(1,2,3) //> 1
//| 2
//| 3