目录
Scala编程进阶
1.Scala函数式编程
(1)Scala的函数
函数是Scala的头等公民
值函数:可以在变量中存放函数
(2)Scala的匿名函数
匿名函数就是没有名字的函数
举例:定义一个匿名函数,作用是对某个数本身乘以3
定义一个数组Array(1,2,3) ,然后使用Array的函数map,作用是通过对这个数组的所有元素应用一个函数来构建一个新集合Array(3,6,9)
(3)Scala的闭包和柯里化
闭包:就是函数的嵌套,即在定义一个函数的时候,包含了另外一个函数的定义,在内函数中,可以访问外函数的变量
到目前为止,所有函数的例子仅参考了传入的参数,例如(x:Int) => x>0里,函数体x>0用到的唯一变量x被定义为函数参数。然而,当函数定义为(x:Int)=> x+more时,函数把“more”加入参考,但什么是more呢?从这个函数来看,more是个自由变量,因为函数字面量没有给出其含义。相对的,变量x是一个绑定变量,因为它在函数的上下文中有明确意义,被定义为函数的唯一参数。如果尝试独立使用这个函数字面量,而范围内并没有任何more的定义,则编译器会报错。
另一方面,只要有一个叫做more的某种东西,同样的函数字面量将工作正常。依靠这个函数字面量在运行时创建的函数值(对象)被称为闭包。名称源自于通过“捕获”自由变量的绑定,从而对函数字面量执行的“关闭”行动。
上面的例子,创建了一个函数makeIncreaser,x是这个函数的绑定变量,而more是个自由变量,more的值取决于外界传入的值,从而成为一个闭包。当定义inc1函数时,每次调用makeIncreaser都会创建一个新闭包,每个闭包都会访问闭包创建时活跃的more变量,在这个例子里,more=1,当more被定下来之后,inc1的值也可以被定下来了。
下划线表示List里的任一数字,因此sum成为了一个闭包,因为累加的值并不固定
柯里化(Currying)
使函数柯里化的意思是,把具有多个参数的函数转换成一条函数链,在每个节点上都是单一的函数参数
首先我们定义一个函数:def add(x:Int,y:Int) = x+y
等价于这种柯里化写法:def add(x:Int)(y:Int) = x+y
那么是怎么实现的呢
add(x)(y)实际上是依次调用两个普通函数,第一次调用使用一个参数x,返回一个函数类型的值,第二次使用参数y调用这个函数类型的值,实质上最先演变成这样一个方法:def add(x:Int) = (y:Int) => x+y,闭包right?y是add函数的绑定变量,x是自由变量,当定义一个val add1=add(1)的时候,调用add(1),捕获值1作为x的绑定的闭包被创建并返回,因此add1(2)=3
(4)Scala高阶函数
高阶函数即以函数作为参数的函数
第一个是普通函数,而第二个是高阶函数,someAction函数的参数是函数f,f属于匿名函数,也就是说,f(x)函数的参数是Double,返回值是Double,而这里的x=10,someAction所要返回的值,就是f(10)
举一个具体的例子
可以看到定义了一个普通函数mytest,传入两个Int,返回值也是Int,作用是将两个数相乘再加上100
myfunc1是属于模块化编程,调用mytest来计算传入的参数a和b,返回值同样设为Int
myfunc属于高阶函数,定义了一个匿名函数f(Int,Int),f的返回值是Int,而a和b是myfunc的参数,myfunc的返回值类型是Int,返回值是f(a,b)。用一个比较直白的例子就是sqrt(sqr(x)),对x求了乘方然后再开方,对于函数sqrt而言,他的参数就是函数sqr(x)。高阶函数可以使我们开发出来的程序非常简洁。
Scala常用高阶函数
定义一个集合:val numbers = List(1,2,3,4,5,6,7,8,9,10)
(1)map:对集合中的每个元素执行一个函数运算,返回一个包含相同数目的新的集合
举例:集合中所有乘以2
(2)foreach: 类似map,对集合中的每个元素执行一个函数运算,跟map的区别是没有返回值
(3)filter: 过滤,相当于SQL中where
举例:选择能够被2整除的元素
(4)zip: 把两个列表的元素合并到一个由元素对组成的新的列表中
(5)partition:分区,根据条件(断言)的返回值对列表进行分区
(6)find: 查找第一个满足条件的元素
(7) flatten:把一个嵌套的结构展开