偏函数
- 偏函数(Partial Function),是一个数学概念它不是"函数"的一种, 它跟函数是平行的概念
- Scala中的偏函数是一个trait,其的类型为PartialFunction[-A,+B],"-"符号表示逆变,-A表明输入参数为A类型或A类型的父类,也就是说输入的参数应为A的子集; "+"符号表示协变,+B表示可以是B类型或B类型的子类
def funPartial:PartialFunction[Int,String] = {
case 1=>"One"
case 2=>"Two"
case 3=>"Three"
case _=>"Other"
}
println(funPartial(1)) // One
println(funPartial(5)) // Other
println(funPartial("1")) // 编译报错
- 在上个例子中因为有case _=>"Other"这一句,只要输入类型为Int就都是正确的,因为有但如果换成其他类型就会报错。再定义一个函数,去掉case _这一句
def funPartial2:PartialFunction[Int,String] = {
case 1=>"One"
case 2=>"Two"
case 3=>"Three"
}
println(funPartial(1)) // One
println(funPartial(5)) // 运行时报错MatchError
当我们想要验证传入的值是否在函数的定义域中,每次都编写函数验证显得过于麻烦,scala偏函数内部为我们提供了一些方法,如:isDefinedAt、OrElse、 andThen、applyOrElse等等。
- isDefinedAt
这个函数的作用是判断传入来的参数是否在这个偏函数所处理的范围内,当在范围内时,它返回一个true,反之false
def funPartial:PartialFunction[Int,String] = {
case 1=>"One"
case 2=>"Two"
case 3=>"Three"
}
println(funPartial.isDefinedAt(1)) // ture
println(funPartial.isDefinedAt(5)) // true
// println(funPartial.isDefinedAt("1")) // 编译报错
- orElse
将多个偏函数组合起来使用
def fun:PartialFunction[Int,String] = {
case 1=>"One"
}
def fun2:PartialFunction[Int,String] = {
case 2 =>"Two"
}
def fun3 = fun orElse fun2
println(fun3(1)) // One
println(fun3(2)) // Two
- andThen
简单的说就是方法的连续调用,将前一个函数的输出当做后一个的输入
def fun:PartialFunction[Int,String] = {
case 1=>"One"
}
def fun2:PartialFunction[String,String] = {
case "One" => "this is one"
}
def fun3 = fun andThen fun2
println(fun3(1)) // this is one
注意:无论是前一个函数还是后一个函数遇到没有匹配的值,都会抛出异常
- applyOrElse
该方法接收2个参数,第一个是调用的参数,第二个是个回调函数。如果第一个调用的参数匹配,返回匹配的值,否则调用回调函数 - 自定义偏函数
object PartitialFunction {
def main(args: Array[String]): Unit = {
val pf: PartialFunction[Any, Int] = new PartialFunction[Any, Int] {
override def isDefinedAt(x: Any): Boolean = {
if (x.isInstanceOf[Int])
true
else
false
}
override def apply(v1: Any): Int = {
v1.asInstanceOf[Int] + 1
}
}
val list = List(1,2,4,"four")
list.collect(pf).foreach(println)
}
}
def fun:PartialFunction[Int,String] = {
case 1=>"One"
}
println(fun.applyOrElse(1, { num: Int => "other" })) // One
println(fun.applyOrElse(2, { num: Int => "other" })) // other
部分应用函数
- 部分应用函数又称偏应用函数,但它与偏函数有着很大的区别
- 当在调用一个函数时,把这个函数应用到参数中。 如果传递所有预期的参数,则表示您已完全应用它。
如果只传递几个参数并不是全部参数,那么将返回部分应用的函数。这样就可以方便地绑定一些参数,其余的参数可稍后填写补上。
// 三个数a、b、c相加,已知a=10
def add(a:Int,b:Int,c:Int):Int={
a+b+c
}
// 调用函数
add(10,1,3)
add(10,2,8)
运行上述代码时,我们发现a的值是已知的,每次调用函数都要重复写,比较麻烦,解决此问题就可以用部分函数
// 三个数a、b、c相加,已知a=10
def add(a:Int,b:Int,c:Int):Int={
a+b+c
}
// 用一个变量存储a的值
val a = 10
// 部分函数
def add2=add(a,_:Int,_c:Int) //两个_分别代指add函数中的b、c两个变量
// 调用函数
add2(8,6)