如果你想定义一个函数,而让它只接受和处理其参数定义域范围内的子集,对于这个参数范围外的参数则抛出异常,这样的函数就是偏函数(顾名思异就是这个函数只处理传入来的部分参数)。

偏函数是个特质其的类型为PartialFunction[A,B],其中接收一个类型为A的参数,返回一个类型为B的结果。
其有个重要的函数就是:
def isDefinedAt(x: A): Boolean //作用是判断传入来的参数是否在这个偏函数所处理的范围内

定义一个普通的除法函数:

scala> val divide = (x : Int) => 100/x
divide: Int => Int = <function1>
输入参数0
scala> divide(0)
java.lang.ArithmeticException: / by zero 
显然,当我们将0作为参数传入时会报错,一般的解决办法就是使用try/catch来捕捉异常或者对参数进行判断看其是否等于0;但是在Scala的偏函数中这些都已经封装好了,如下:将divide定义成一个偏函数()
val divide = new PartialFunction[Int,Int] {
def isDefinedAt(x: Int): Boolean = x != 0 //判断x是否等于0,当x = 0时抛出异常
def apply(x: Int): Int = 100/x
}  
但是,当偏函数与case语句结合起来就能使代码更简洁,如下:
val divide1 : PartialFunction[Int,Int] = {
case d : Int if d != 0 => 100/d //功能和上面的代码一样,这就是偏函数的强大之处,方便,简洁!!
} 
其实这代码就是对上面那段代码的封装,这里同样调用isDefinedAt方法
scala> divide1.isDefinedAt(0)
res1: Boolean = false scala> divide1.isDefinedAt(10)
res2: Boolean = true 
再举个与case结合使用的例子:
val rs : PartialFunction[Int , String] = {
case 1 => "One"
case 2 => "Two"
case _ => "Other"
}
输入:
scala> rs(1)
res4: String = One scala> rs(2)
res5: String = Two scala> rs(100)
res6: String = Other
 
OrElse
OrElse方法可以将多个偏函数组合起来使用,结合起来的效果类似case语句,但是每个偏函数里又可以再使用case
scala> val or1 : PartialFunction[Int,String] = {case 1 => "One"}
or1: PartialFunction[Int,String] = <function1> scala> val or2 : PartialFunction[Int,String] = {case 2 => "Two"}
or2: PartialFunction[Int,String] = <function1> scala> val or_ : PartialFunction[Int,String] = {case _ => "Other"}
or_: PartialFunction[Int,String] = <function1> scala> val or = or1 orElse or2 orElse or_ //使用orElse将多个偏结合起来
or: PartialFunction[Int,String] = <function1> scala> or(1)
res7: String = One scala> or(20)
res9: String = Other
orElse还可以直接连接case使用
scala> val orCase:(Int => String) = or1 orElse {case _ => "Other"}
orCase: Int => String = <function1> scala> orCase(1)
res10: String = One scala> orCase(10)
res11: String = Other
  
 
andThen
对函数的结果进行下一步的处理
scala> val at1 : PartialFunction[Int,String] = {case cs if cs == 1 => "One"}
at1: PartialFunction[Int,String] = <function1> scala> val at2 : PartialFunction[String,String] = {case cs if cs eq "One" => "The num is 1"}
at2: PartialFunction[String,String] = <function1> scala> val num = at1 andThen at2
num: PartialFunction[Int,String] = <function1> scala> num(1)
res18: String = The num is 1
 
注意:at1函数的结果返回类型必须和at2函数的参数传入类型一致,不然会编译报错
 

Scala-Partial Functions(偏函数)的更多相关文章

  1. Partial Functions(偏函数)

    如果你想定义一个函数,而让它只接受和处理其参数定义域范围内的子集,对于这个参数范围外的参数则抛出异常,这样的函数就是偏函数(顾名思异就是这个函数只处理传入来的部分参数). 偏函数是个特质其的类型为Pa ...

  2. Python partial function 偏函数

    Partial function 偏函数是将所要承载的函数作为partial()函数的第一个参数,原函数的各个参数依次作为partial()函数后续的参数,除非使用关键字参数. 当函数的参数个数太多, ...

  3. Python使用functools模块中的partial函数生成偏函数

    所谓偏函数即是规定了固定参数的函数,在函数式编程中我们经常可以用到,这里我们就来看一下Python使用functools模块中的partial函数生成偏函数的方法 python 中提供一种用于对函数固 ...

  4. Scala中的偏函数与部分应用函数

    Scala中有PartialFunction的概念, 同时还要一个概念叫Partial Applied Function. 前者译作偏函数, 后者译作"偏应用函数"或"部 ...

  5. Scala Partial Function从官方文档解析

    A partial function of type PartialFunction[A, B] is a unary function where the domain does not neces ...

  6. Scala:Functions and Closures

    object Functions { def main(args: Array[String]) { // 本地函数 def localFun(msg: String) = println(msg) ...

  7. Scala方法定义,方法和函数的区别,将方法转换成函数

    1. 定义方法和函数 1.1. 定义方法 方法的返回值类型可以不写,编译器可以自动推断出来,但是对于递归函数,必须指定返回类型 1.2. 定义函数 1.3.方法和函数的区别 在函数式编程语言中,函数是 ...

  8. Scala偏函数与部分函数

    函数 1.部分函数 部分应用函数(Partial Applied Function)是缺少部分参数的函数,是一个逻辑上概念. def sum(x: Int, y: Int, z: Int) = x + ...

  9. scala偏函数

    package com.ming.test /** * 在Scala中,偏函数是具有类型PartialFunction[-T,+V]的一种函数.T是其接受的函数类型,V是其返回的结果类型. * 偏函数 ...

随机推荐

  1. class 类(1)

    创建类 #!/usr/bin/env python # coding=utf-8 __metaclass__ = type class Person: def __init__(self, name) ...

  2. 【转】WCF、WebAPI、WCFREST、WebService之间的区别

    在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下,你有很多的选择来构建一个HTTP Services.我分享一下我对 ...

  3. 【leetcode】Merge Sorted Array(合并两个有序数组到其中一个数组中)

    题目: Given two sorted integer arrays A and B, merge B into A as one sorted array. Note: You may assum ...

  4. opencv 实现进度控制

    进度控制: #include <opencv\cv.h> #include <opencv\highgui.h> #include <opencv\cxcore.h> ...

  5. ajax(ajax开发)

    AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术. AJAX = 异步 JavaScript和 ...

  6. javascript 模仿 html5 placeholder

    <form action="?action=deliver" method="post" class="deliver-form"&g ...

  7. Android -------- API等级

      API等级 Android版本 代号名称(基本上是按ABC命名排序的) 注释说明 1 Android 1.0     2 Android 1.1 Petit Four   3 Android 1. ...

  8. silverlight visifire控件图表制作——silverlight 后台方法画图

    1.调用wcf 获取信息 private void svc_GetSingleChartDataCompleted(object sender, GetSingleChartDataCompleted ...

  9. iOS学习笔记-CoreData

    简介 CoreData提供了对象关系映射(ORM)功能,从效果上说就是创建了一个"虚拟对象数据库",也可以把它看作一个综合的数据库管理库. NSManagedObjectConte ...

  10. C#按键打开文件选择对话框,并把选择好的路径保存/显示到textBox

    1.选择文件夹 FolderBrowserDialog fbd = new FolderBrowserDialog(); fbd.SelectedPath = "D:";//默认路 ...