沒有名字的函式就是匿名函式,格式:(x:int)=>
x:表示輸入引數型別;int:表示輸入引數型別;函式體:表示具體**邏輯
傳遞匿名函式至簡原則:
引數的型別可以省略,會根據形參進行自動的推導;
型別省略之後,發現只有乙個引數,則圓括號可以省略;其他情況:沒有引數和引數超過1的永遠不能省略圓括號;
匿名函式如果只有一行,則大括號也可以省略 ;
如果引數只出現一次,則引數省略且後面引數可以用_代替;
objectfunctiontest04
//func: string=> unit 表示傳入乙個引數為string型別,返回值為unit型別的函式變數
//f就是乙個引數為函式型別,返回值為unit的普通函式
def f(func: string=> unit): unit =
//這兩個意思完全相同
f(fun)
f((s: string) =>)
//1、匿名函式簡化:函式的引數只有乙個或者沒有,可以省略小括號
//函式體只有一句可以省略大括號
f(s =>println(s))
//2、匿名函式簡化:當函式的引數只有乙個且只出現一次時,該引數的名字可以是任意的名字
//因此,也可以用萬用字元「_」來表示
f(println(_))
//3、匿名函式簡化:如果可以推斷出println是函式體,而不是呼叫的語句,可以直接省略"_"
//注意:小括號必須要省略,否則會認為是呼叫語句
f(println)
}}
多個引數的匿名函式應用:
//多引數的匿名函式
def caculator(a: int,b: int,op: (int,int) => int):int =
//1、標準版
println(caculator(2,3,(x: int,y: int) => ))
//2、省略花括號以及引數型別
println(caculator(2,3,(x,y) => x +y))
//3、由於x,y只出現了一次,故也可以簡化
println(caculator(2,3,_ + _))
2.1 函式作為值進行傳遞
//函式的定義
def fun3():unit =
//呼叫函式
fun3()
//函式作為值傳遞
//這相當於呼叫一次fun3函式
//var v = fun3()
var v =fun3
//將函式傳遞給變數的標準形式
var v1: ()=>unit =fun3
//簡化形式, _代表fun3後面的函式體
var v2 = fun3 _
2.2 函式作為引數傳遞
//定義乙個加法函式
def add(a: int,b: int): int = a +b
//這個函式的引數是函式簽名(by-name),f表示函式名稱,(int,int)表示函式的輸入型別
//箭頭後的int表示返回型別
//這種方式相當於只傳入行為
//函式體中定義了資料
def caculators(f: (int,int) => int):int =
//將add作為引數傳遞給caculators
//如果能推斷出不是呼叫,也可以把 _省略
println(caculators(add _))
println(caculators(add))
2.3 函式作為函式返回值返回
//函式作為返回值返回
def f1() =
//這是f1的返回
f2 _
}//因為呼叫f1的返回值是個函式f2,所以變數v3可以繼續呼叫
var v3 =f1()
v3()
//以上兩部可以簡化為
f1()()
objectfunctiontest05
else
}fun(
0,"",'0'
)
/** 練習2: 定義乙個函式func,它接收乙個int型別的引數,返回乙個函式(記作f1)。
* 它返回的函式f1,接收乙個string型別的引數,同樣返回乙個函式(記作f2)。
* 函式f2接收乙個char型別的引數,返回乙個boolean的值。
* 要求呼叫函式func(0) (「」) (『0』)得到返回值為false,其它情況均返回true。
* */def func (i:int) =
else
}//返回函式 f2
f2 _
}//返回函式f1
f1 _
}func(
0)("")('0'
) }
}
/** 模擬map對映、filter過濾、reduce聚合
* *///
1、模擬map對映
//array 代表傳入資料
//op 代表傳入的操作函式
def map(array: array[int], op: int => int): array[int] =
//定義陣列
var arr: array[int] = array(10,20,30,40
)
//定義操作:資料加1
def addone(i: int):int = i+1
//呼叫map函式
//map(arr,addone) 返回的是乙個引用型別,需要使用mkstring方法
println(map(arr,addone).mkstring(","
)) }
輸出:11,21,31,41
//接上面**,簡化操作
//例如:所有元素乘2
var arr2 = map(array(10,20,30,40),_ * 2
)println(arr2.mkstring(",
"))輸出:20,40,60,80
def main(args: array[string]): unit =arr.toarray
}//排除陣列中的偶數
var arr1 = filter(array(1,2,3,4,5,6), _ % 2 == 1
)
//列印輸出
println(arr1.mkstring(","
)) }
def main(args: array[string]): unit =//返回 init
init
}//輸入陣列以及累加操作
println(reduce(array(1,2,3,4),_ +_))
}
閉包:函式式程式設計的標配 ,如果乙個函式,訪問到了它的外部變數的值,那麼這個函式和他所處的環境,稱為閉包 ;
函式柯里化:把乙個引數列表的多個引數,變成多個引數列表。
def main(args: array[string]): unit =}//2、柯里化示例
def add(a: int,b: int) =
//變為如下形式,就是柯里化
def addcur(a: int)(b: int) = a +b
//具體實現過程是,先演變為:
//實際就是函式add1中巢狀了乙個匿名函式: (b: int) => a + b
def add1 (a: int) = (b: int) => a +b
}
注意:在scala的遞迴中,必須宣告函式返回值型別
def main(args: array[string]): unit =def test(i: int):int =
}
scala的直譯器在解析函式引數(function arguments)時有兩種方式:
傳值呼叫:先計算引數表示式的值,再應用到函式內部;
傳名呼叫:將未計算的引數表示式直接應用到函式內部。
注意:j**a只有值呼叫;scala既有值呼叫,又有名呼叫。
def main(args: array[string]): unit =def time() =
def delayed(t: => long) =
當函式返回值被宣告為lazy時,函式的執行將被推遲,直到我們首次對此取值,該函式才會執行。這種函式我們稱之為惰性函式。
def main(args: array[string]): unit =def sum(a: int,b: int) =
輸出:----------------------sum 被執行了
v=5
scala函式高階篇
1 求值策略 scala裡有兩種求值策略 call by value 先對函式實參求值,在函式體中用這個求出的引數值。call by name 先不對函式實參求值,而是函式實參每次在函式體內被用到時都會求值。scala通常使用call by value 如果函式形參型別以 開頭,那麼就是在使用cal...
Scala高階函式
在scala中,無法直接操縱方法,只能直接操縱函式,所以需要使用 import scala math.val temp ceil val num 3.14 println fun temp num temp的型別是 double double,意為接受double引數並返回double的函式。能夠對...
Scala 高階函式
import scala.math.val num 3.14val func ceil 意味著確實指的是這個函式,而不是忘記了傳引數 func是乙個函式變數,內容儲存的是個函式 val v func num println v val arr array 1.0,3.14,4 map func 將函...