Scala函数式编程专题--scala集合和函数

2020-06-29 14:00:59丽君

二.scala函数

在最前面有介绍到,函数就是对象。那为什么函数能直接运行呢?这其实得益于object的apply这个语法糖。

偏函数

偏函数(PartialFunction),从某种意义上来说,偏函数也是scala中挺重要的一个语法糖。

偏函数它长这样:

PartialFunction[A, B] //接收一个A类型的参数,返回B类型的参数

值得一提的是,scala中有一个关键字case,就是使用偏函数。继续举例子:

//下面的case就是一个偏函数PartialFunction[Int, String]
scala> val one: PartialFunction[Int, String] = { case 1 => "one" }
one: PartialFunction[Int,String] = <function1>

scala> one(1)
res11: String = Int

scala> one("one")
<console>:13: error: type mismatch;
 found : String("one")
 required: Int
 one("one")

case关键字会匹配符合条件的类型或值,如果不符合,会报错。内部实现就不介绍了,知道是个常用语法糖就好。

而这个case关键字也正是实现scala模式匹配中,必不可少的一环,有兴趣的童鞋可以看看我这篇:scala模式匹配详细解析

这里再说一个常见应用吧,函数组合子中有一个collect,它需要的参数就是一个偏函数。下面看个有意思的例子:

//这个list里面的Any类型
scala> val list:List[Any] = List(1, 3, 5, "seven")
list: List[Any] = List(1, 3, 5, seven)

//使用map会报错,因为map接收的参数是普通函
scala> list.map { case i: Int => i + 1 }
scala.MatchError: seven (of class java.lang.String)
 at $anonfun$1.apply(<console>:13)
 at $anonfun$1.apply(<console>:13)
 at scala.collection.immutable.List.map(List.scala:277)
 ... 32 elided

 //但如果用collect函数就可以,因为collect接收的参数是偏函数,它会自动使用偏函数的一些特性,所以可以自动过滤掉不符合的数据类型
scala> list.collect { case i: Int => i + 1 }
res15: List[Int] = List(2, 4, 6)

因为collect接收的参数是偏函数,它会自动使用偏函数的特性,自动过滤不符合的数据类型,而map就做不到。

部分应用函数

所谓部分应用的意思,就是说,当调用一个函数时,可以仅传递一部分参数。而这样会生成一个新的函数,来个实例看看吧:

//定义一个打印两个输出参数的函数
scala> def partial(i:Int,j:Int) : Unit = {
 | println(i)
 | println(j)
 | }
partial: (i: Int,j: Int)Unit

//赋一个值给上面那个函数,另一个参数不赋值,生成一个新的函数
scala> val partialFun = partial(5,_:Int)
partialFun: Int => Unit = <function1>

//只要一个参数就可以调用啦
scala> partialFun(10)
5
10

部分应用函数,主要是作用是代码复用,同时也能够增加一定的代码可读性。

当然还有更多有意思的用法,后面有机会说到再说。