Scala函数式程序设计原理 week4 Types and Pattern Matching

函数作为对象

事实上,类型A=>B是类scala.Function[A,B]的缩写,定义如下

package scala
trait Function[A,B]{
def apply(x:A):B
}

所以函数是带有apply方法的对象。
匿名函数

(x:Int)=>x*x

可以展开为

{
class AnonFun extends Function[Int,Int]{
  def apply(x: Int) = x * x
}
new AnonFun
}

或者,使用匿名类语法

new Function[Int,Int]{
def apply(x:Int) = x * x
}

类型变量界定

def assertAllPos[S<:IntSet](r:S):S=...

<: IntSet是类型参数S的上届。意味着S只能是IntSet的子类型。
混合界定

[S>:NonEmpty <: Intset]

型变

通常来说,一种能够接受元素改变的类型是不应该协变的。
但是不可变类型可以协变,只要方法满足一些条件。

函数的子类型化规则

一般来说,如果A2 <: A1并且B1 <: B2
那么,A1=>B1 <: A2 => B2
函数和他们的参数是逆变的,和返回类型是协变的。
这引出了如下的修正定义

package scala
trait Function[-T,+U]{
  def apply(x:T): U
}

析构

匹配语法

match表达式

  • match后跟随一系列cases,pat => expr
  • 每一个样例关联一个表达式和模式
  • 若没有匹配到的模式会抛出MatchError异常
e match{
case pat => expr
case pat => expt
case _ if expr => expr
case _ => expt
}

case _ 捕获所有。
match是表达式,不是语句。
模式可以有以下几种类型构成

  • 构造器
  • 变量
  • 通配符
  • 常数

变量必须以小写字母开头,常量以大写字母开头,除了保留字null,true,false

守卫

守卫可以是任何Boolean条件

样例类

样例类是一种特殊的类,它们经过优化以被用于模式匹配。

abstract class Amount
case class Dollar(value:Double) extends Amount
case class Currency(value:Double,unit:String) extends Amount

当有一个类型为Amount的对象时,可以用模式匹配来匹配到它的类型,并将属性值绑定到变量。

amt match{
case Dollar(v) => "$" + v
case Currency(_,u) => "I got" + u
case Nothing => ""
}

偏函数

被包在括号内的一组case语句是一个偏函数,一个并非对所有输入值都有定义的函数。他是PartialFunction[A,B]的一个实例。该类有两个方法,apply方法从匹配到的模式计算函数值,而isDefinedAt方法在输入至少匹配其中一个模式时返回true。

trait PartialFunction[-A,+R] extends Function[-A,+B]{
def apply(x:A)R
def isDefinedAt(x:A):Boolean
}

上面这个例子结果为trueisDefinedAt只保证偏函数最外层的模式匹配块可以匹配,但不保证不会抛出matcherror

全部评论

相关推荐

28小凳也想实习:项目不用一个业务一个轮子吗,刷牛客好多人说要一业务一轮子
点赞 评论 收藏
分享
02-16 10:35
已编辑
西安科技大学 后端
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务