在介绍scala的第一篇博客里边我就大概介绍了一下为什么函数对于scala这么重要,为什么叫第一公民,在java中什么是第一参数,变量,因为他可以存在于任何地方,无论是全局变量,还是局部变量,还是参数,都可以存在,而scala中,函数同样可以。
如何像变量一样使用
普通函数
定义在函数内的函数,为什么函数内部还能定义函数呢,很简单,因为他是第一公民,他可以让函数来充当变量,或者说函数和变量对于他来说没什么差别。
@Test
def testanonymous() = {
def fun = (x: Double) => 3 * x
Array(3.14, 1.43, 11.56).map(fun).foreach(a => println(a))
}
当然可以这么用,不定义,直接用
Array(3.14, 1.43, 11.56).map((x: Double) => 3 * x).foreach(a => println(a))
柯里函数
柯里转换函数接受多个参数成一条链的函数,每次取一个参数。柯里函数是具有多个参数列表定义,如下:
def strcat(s1: String)(s2: String) = s1 + s2
或者
def strcat(s1: String) = (s2: String) => s1 + s2
使用方法如下:
def mulBy1(factor: Double) = (x: Double) => x * factor
def mulBy2(factor: Double)(x: Double) = x * factor
//mulBy(3)得到的结果依然是一个函数,例如我们val fun = mulBy(3),那么fun函数的结果就是参数乘以三的的函数
val result = mulBy2(3)(4)
就可以得到结果就是12,至于这么用,我们来看看由柯里化的重要性,高阶函数。
高阶函数
其实高阶函数就是柯里化的一种,但是我为什么要分开讲呢,哈哈,我愿意。
好吧,好好说话,其实高阶函数就是把咱们讲的东西的第一种普通函数和第二种函数的合体,即参数就是函数。那么作用是什么呢。先举个例子。
def illege[T, R](param: T)(f: T => Unit): Unit = {
try{
f(param)
}catch {
case x: Exception=>{
throw new Exception
}
}
}
//业务处理
def printFirst(count:Long)={
println(count)
@Test
def testCommonFun(): Unit = {
var a = 100L
illege(a)(printFirst)
}
单看那一个方法好像都不怎么样嘛,貌似也没什么花样,那么我们接下来把他合起来看看。
def fun(count:Long): Unit ={
try{
println(count)
}catch {
case x: Exception=>{
throw new Exception
}
}
}
@Test
def test(): Unit ={
fun
}
有没有发现我们把核心业务处理取了出来,而且即使还有别的类似的方法,我再也不用单独写try catch这些代码了,尽管很多的方法都需要,可是我确实不是很想写呀,怎么办,就这么办。当然我们对于高阶函数还可以这么用。
def illege[T, R](param: T)(f: T => Unit): Unit = {
try{
f(param)
}catch {
case x: Exception=>{
throw new Exception
}
}
}
@Test
def testCommonFun(): Unit = {
var a = 100L
illege(a){
a=>
println(a)
}
}
这样我们以后就可以专心干我们的业务逻辑了,而不是不想一直写try catch,还得必须要写。你说烦不烦。
小结
官家解释:函数定义可以出现在在源文件的任何地方,Scala允许嵌套函数的定义,那就是其他函数定义的内部函数定义。
本人小结:一个类里边,你能写东西的地方,函数都可以存在,所以第一公民当值无愧