模式匹配
本章学习Scala中十分强大的模式匹配机制,同时Scala提供了样例类,对模式匹配进行了优化。
本文主要学习模式匹配,样例类知识点击阅读: 样例类
一、模式匹配
Scala中的模式匹配类似于Java中的switch语法,但是更加强大。
模式匹配语法中,采用match关键字声明,每个分支采用case关键字进行声明。
当需要匹配时,按照从上到下顺序匹配。会从第一个case分支开始,如果匹配成功,那么执行对应的逻辑代码,如果匹配不成功,继续执行下一个分支进行判断。
如果所有case都不匹配,那么会执行case _ 分支,类似于Java中default语句。语法上允许多个case _分支,但是只会匹配第一个case _分支。后面的无效。
1.基础案例
案例:匹配操作符,根据不同的操作符,给sign赋值。
var sign = ...
val ch: Char = ...
ch match{
case '+' => sign = 1
case '-' => sign = -1
case _ => sign = 0
}
与if类似,match也是一个表达式,而不是语句。上述代码可以简化为:
var sign = ...
val ch: Char = ...
sign = ch match{
case '+' => 1
case '-' => -1
case _ => 0
}
细节说明:
1. match 和 case 是关键字,匹配的顺序是从上到下。如果匹配成功, 则 执行 => 后面的代码块。
2.每个case中,不用break语句,自动中断case,自动的退出match。
3.所有case都不匹配,会执行case _ 分支。如果所有case都不匹配,又没写case _ ,会抛出MatchError
4.=> 后面的代码块到下一个 case, 是一个整体,可以使用{} 扩起来。
5.可以在match中使用其它类型,而不仅仅是字符。
2.模式守卫
有时模式匹配不够精准,如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫。
比如我们想要扩展自己的示例,以匹配所有的数字:
var sign = ...
val ch: Char = ...
var digit: Int =...
ch mathch {
case '+' => sign = 1
case '-' => sign = -1
//匹配所有的数字。 Character.digit()在指定的基数返回字符ch的数值.这里返回ch的10进制数。
case _ if(Character.isDigit(ch))) => digit = Character.digit(ch,10)
case _ => sign = 0
}
细节说明
1.守卫可以任何Boolean条件表达式
2. case _ 后面有条件守卫if时, 这时的下划线 _ 不是表示默认匹配,而是match传入变量ch的简写。即等价
case ch if(Character.isDigit(ch))) => digit = Character.digit(ch,10)
二、模式种类
模式匹配有很多种类,模式的语法很容易理解,且模式与相应的表达式几乎相同,所以很容易掌握。本小节主要介绍:通配模式、常量模式、变量模式、构造方法模式、序列模式、元组模式、带类型的模式、变量绑定。
1.通配模式
通配模式(_)会匹配任何对象。前面已经看到过通配模式用于缺省、捕获所有的可选路径,就像这样:
var sign = ...
val ch: Char = ...
sign = ch match{
case '+' => 1
case _ => 0 //通配模式
}
通配模式还可以用来忽略某个对象中你并不关心的局部。例如BinOp是个二元操作函数,可能你并不需要关心二元操作的操作元是什么,它只是检查这个表达式是否是二元操作:
expr match {
case