一、函数的定义
1、函数独立定义
在Scala中,函数时通过关键字def来定义的,如下面代码:
scala> def fun1(name: String) = println(name)
fun1 : (name:String)Unit
2、将函数复制给变量,赋值中,函数名后面要加空格和下划线:
scala>val fun2 = fun1_
fun2:String => Unit = <function1>
3、匿名函数复制给变量,语法格式:val 变量名 = (参数名 : 类型,如String) =>函数体:
scala>val fun3 = (cont:String) => println(cont)
fun2 : String => Unit =<function1>
二、高阶函数
1、概述:
在Scala中,函数的参数为函数时,这样的函数就是高阶函数。
2、举例说明:
scala> def bigData(func : String => Unit, cont: String) = func(cont)
bigData : (func:String => Unit, cont:String)Unit
说明:定义了一个bigData函数,第一个参数为一个函数,第二个参数为一个字符串,那么这样的函数就是一个高阶函数。
下面是使用这个高阶函数:
scala>bigData(func3, "Scala")
Scala
如上面代码所示,调用这个高阶函数时,传递了被赋值为函数的变量fun3,和一个字符创Scala。
2.2、高阶函数的返回值,也可以是函数,如例:
scala> def fun_returned(cont:String) = (msg:String) => println(cont + " " + msg)
fun_returned: (cont:String)String => Unit
scala> val returned = fun
fun1 fun2 fun3 fun_returned
scala> val returned = fun_returned("scala")
returned: String => Unit = <function1>
scala> returned("Spark")
scala Spark
1)上面定义的函数fun_returned,它有一个参数cont,同时我们又将一个匿名函数赋给了这个函数,也就是说这个函数fun_returned的返回值就是这个匿名函数。
2)当给变量returned赋值函数fun_returned时,我们看到这个变量类型是String的,而这个String的返回值为Unit的一个函数。
2.3、在高阶函数的函数的函数体中,只使用了一次函数的输入参数的值,此时,我们可以将参数的名称省略掉,用下划线(_)代替。如:
scala> def spark(func : (String) => Unit, name:String) {func(name)}
spark : (func:String => Unit, name : String)Unit
scala> spark(name:String => println(name), "Scala")
Scala
scala> spark((name) => println(name), "Scala")
Scala
scala> spark(name => println(name), "Scala")
Scala
scala> spark(println(_), "Scala")
Scala
scala> spark(println, "Scala")
Scala
scala> val arr = Array(1,2,3,4,5,6)
arr: Array[Int] = Array(1, 2, 3, 4, 5, 6)
scala> arr.map(2*_)
res0: Array[Int] = Array(2, 4, 6, 8, 10, 12)
三、函数的闭包
3.1、概述:
scala函数的闭包,是指函数的变量超出其有效的作用域后,仍然对函数的内部变量进行访问,那么这样的函数就叫做闭包函数。
3.2、举例说明:
scala> def scala(cont: String) = (msg:String) => println(cont + "--" + msg)
scala: (cont:String)String => Unit
scala> val fun_result = scala("Spark")
fun_result: String => Unit = <function1>
scala> fun_result("Flink")
Spark--Flink
如上面例子所示,当在将Spark传入函数scala时,Spark理应作为scala函数的内部变量,其作用域为scala函数体中,但当我们在调用变量fun_result时,这个变量调用了scala内部的变量cont(值为Spark),这就是函数的闭包。
四、柯里化函数
4.1、定义:
柯里化就是指把接受多个函数变成接受一个单一参数的函数,而且返回接受余下参数并返回结果的函数。
4.2、举例说明:
1)正常情况下,我们的求和函数定义为:
scala> def sum(x:Int, y:Int) = x+y
sum: (x: Int, y: Int)Int
scala> sum(1, 3)
res0: Int = 4
2)然后我们可以改变一下,使用上面学过的闭包来定义这样的一个函数:
scala> def sum2(x:Int) = (y:Int) => x+y
sum2: (x:Int)Int => Int
scala> val fun1 = sum2(2)
<console>:12: error: not enough arguments for method sum: (x: Int, y: Int)Int.
Unspecified value parameter y.
val fun1 =sum(2)
^
scala> fun1(4)
res0: Int = 6
说明:在上面,我们定义了使用闭包的函数。那么我们在使用函数的时候,可以转换一种思路,如下所示:
scala> sum2(3)(5)
res1: Int = 8
** 上面这个使用,其实就是有柯里化的意思了,sum2(3)(5),这个其实首先是调用了sum(x:Int)的函数,然后返回一个函数后,再次调用了匿名的(y:Int)=>x+y函数。
3)好了,下面正式举例柯里化了,如下所示:
scala> def sum3(x:Int)(y:Int)=x+y
sum3: (x:Int)(y:Int)Int
scala> sum3(1)(3)
res2: Int = 4
说明:来看函数sum3,就与我们在上面定义柯里化函数一样了。
五、Scala的reduceLeft函数
这个函数就不做过多的熬述了,直接举例来说明一切:
scala> (1 to 5).reduceLeft(_+_)
res3: Int = 15
说明:上面的(1 to 5).reduceLeft(+)就是1+2+3+4+5的结果,也就是15。