Scala中有一个很有用的traits叫PartialFunction,我看了下别人的翻译叫做偏函数,但是我觉得部分函数更加确切。

那么PartialFunction是做什么用的呢?简单点说PartialFunction用在模式匹配中,是一个不完整的函数,它只实现了函数的部分功能,也就是列举了部分case的情况。

我们先看下PartialFunction的定义:

trait PartialFunction[-A, +B] extends (A => B) { ...def isDefinedAt(x: A): Boolean...

我们可以看到PartialFunction是一个trait,它继承自函数 (A => B), 这个函数有一个参数和一个返回值,在Scala中,该函数会被自动解析为Function1。

我们看下Function1的定义:

trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double) +R] extends AnyRef { self =>/** Apply the body of this function to the argument.*  @return   the result of function application.*/def apply(v1: T1): R

我们可以看到Function1定义了一个方法: def apply(v1: T1): R

PartialFunction也定义了一个方法: def isDefinedAt(x: A): Boolean

如果我们要自己实现一个PartialFunction,则必须实现上述两个方法:

  val inc = new PartialFunction[Any, Int] {override def isDefinedAt(x: Any): Boolean = ???override def apply(v1: Any): Int = ???}

其中isDefinedAt用来选择PartialFunction入参的范围,而apply是真正的业务逻辑。

除了用new来实例化一个PartialFunction外,还有一个最简单的方法就是使用case语句。 我们举个例子, 如果我们有段case逻辑是匹配各个好吃等级,如下:

  println("Step 1: Review of Pattern Matching in Scala")val donut = "Glazed Donut"val tasteLevel = donut match {case "Glazed Donut" | "Strawberry Donut" => "Very tasty"case "Plain Donut" => "Tasty"case _  => "Tasty"}println(s"Taste level of $donut = $tasteLevel")

我们使用了3个case语句,看起来比较繁琐,使用PartialFunction, 我们可以将其转换为如下的形式:

  val donutTaste = isVeryTasty orElse isTasty orElse unknownTasteprintln(donutTaste("Glazed Donut"))println(donutTaste("Plain Donut"))println(donutTaste("Chocolate Donut"))

PartialFunction可以通过使用orElse关键字来合并成一个完整的Function。

我们看下这几个PartialFunction该怎么定义:

  val isVeryTasty: PartialFunction[String, String] = {case "Glazed Donut" | "Strawberry Donut" => "Very Tasty"}val isTasty: PartialFunction[String, String] = {case "Plain Donut" => "Tasty"}val unknownTaste: PartialFunction[String, String] = {case donut1 @ _ => s"Unknown taste for donut = $donut1"}

实际上就是把整个的业务逻辑,用PartialFunction拆分开来了。这里使用case语句,会自动转换成为PartialFunction。

关注下最后一个unknownTaste的case语句, @ 使用来做模式匹配的, case donut1 @ _ 就意味着 donut1 将会匹配所有的输入。

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

更多教程请参考 flydean的博客

Scala教程之:PartialFunction相关推荐

  1. Scala教程之:Future和Promise

    文章目录 定义返回Future的方法 阻塞方式获取Future的值 非阻塞方式获取Future的值 Future链 flatmap VS map Future.sequence() VS Future ...

  2. scala教程之:可见性规则

    文章目录 public Protected private scoped private 和 scoped protected 和java很类似,scala也有自己的可见性规则,不同的是scala只有 ...

  3. Scala教程之:深入理解协变和逆变

    文章目录 函数的参数和返回值 可变类型的变异 在之前的文章中我们简单的介绍过scala中的协变和逆变,我们使用+ 来表示协变类型:使用-表示逆变类型:非转化类型不需要添加标记. 假如我们定义一个cla ...

  4. Scala教程之:Either

    在之前的文章中我们提到了Option,scala中Option表示存在0或者1个元素,如果在处理异常的时候Option就会有很大的限制,因为Option如果返回None,那么我并不知道具体的异常到底是 ...

  5. Scala教程之:可变和不变集合

    文章目录 mutable HashMap immutable HashMap 集合在程序中是非常有用的,只有用好集合才能真正感受到该语言的魅力.在scala中集合主要在三个包里面:scala.coll ...

  6. Scala教程之:Enumeration

    Enumeration应该算是程序语言里面比较通用的一个类型,在scala中也存在这样的类型, 我们看下Enumeration的定义: abstract class Enumeration (init ...

  7. Scala教程之:Option-Some-None

    文章目录 Option和Some Option和None Option和模式匹配 在java 8中,为了避免NullPointerException,引入了Option,在Scala中也有同样的用法. ...

  8. Scala教程之:scala的参数

    文章目录 默认参数值 命名参数 scala的参数有两大特点: 默认参数值 命名参数 默认参数值 在Scala中,可以给参数提供默认值,这样在调用的时候可以忽略这些具有默认值的参数. def log(m ...

  9. Scala教程之:可扩展的scala

    文章目录 隐式类 限制条件 字符串插值 s 字符串插值器 f 插值器 raw 插值器 自定义插值器 Scala是扩展的,Scala提供了一种独特的语言机制来实现这种功能: 隐式类: 允许给已有的类型添 ...

最新文章

  1. ASP.NET MVC5+EF6+EasyUI 后台管理系统(20)-权限管理系统-根据权限获取菜单
  2. win 常用网络命令
  3. iOS 查看崩溃日志
  4. 企业网络推广之中如何对网页设计提出新的色彩搭配原理?
  5. WinForm实现Rabbitmq官网6个案例-Topics
  6. UVA12412 A Typical Homework (a.k.a Shi Xiong Bang Bang Mang)
  7. linux日志服务器配置在哪个文件,Linux中日志的基本配置(syslog)
  8. 源码-03-九宫格 封装 懒加载 plist
  9. Java程序员面试宝典(第4版)
  10. Mysql数据库高可用方案
  11. HDU - 6070 线段树 + 分数规划
  12. Windows简单TCPIP服务
  13. IOS中结构体(struct)
  14. 12万字零碳智慧校园数字化节能监管管控平台建设方案2022
  15. ParaView绘制自由水面的等值线图
  16. mysql报错No operations allowed after statement closed
  17. OpenCV找出图片中的圆并标注圆心
  18. Spring depends-on
  19. Linux Kernel 网络 之 Netlink
  20. 通过 Windows XP Embedded 设备更新代理应用 QFE

热门文章

  1. HDU4622(后缀自动机)
  2. 3_1 StrategyMode.cpp 策略模式
  3. 多进程和多线程的优缺点
  4. Windows I/O模型、同步/异步、阻塞/非阻塞
  5. 复制SQLSERVER数据库文件
  6. 从send函数和sendto函数参数的不同看TCP和UDP的差别
  7. OpenShift 与 OpenStack:让云变得更简单
  8. 基于MySQL和DynamoDB的强一致性分布式事务实践
  9. GitHub:再见,master!
  10. 从上海到旧金山,2021 LiveVideoStackCon回归上海