开发者学堂课程【Scala 核心编程 - 进阶:Match 中的守卫】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/610/detail/9068
Match 中的守卫
基本介绍
如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫。
应用案例
新建命名为 MatchIfDemo01引入下方代码
for (ch <- "+-3!") { //是对"+-3!"的遍历
var sign=0
var digit=0
ch match {
case'+'=> sign=1
case'-'=> sign=-1
//说明..
//如果 case 后有条件守卫即 if,那么这时的_不是表示默认匹配
//表示忽略传入的 ch
case _if ch.toString.equals("3")=> digit=3
case _if ch>10 => println("ch >10 ")
case _=> sign=2
}
//分析
// + 1 0
// - -1 0
// 3 0 3
// 1 2 0
printin(ch + " " + sign +" "+ digit)
}
为了证明可以使用范围加入 case_if ch>10 => println("ch >10 ")
首先匹配到+与 case'+'=> sign=1匹配,ch为+ sign为1,digit没有任何改变仍然为0。
第二个匹配到-与case'-'=> sign=-1匹配,printin(ch + " " + sign +" "+ digit)包在for循环里,sign被修改成-1,digit没有任何改变仍然为0。
第三个匹配到3,3不等与+也不等于-,
与 case_if ch.toString.equals("3")=> digit=3匹配。
第四个匹配到!,!既不匹配+也不匹配-,与case_=> sign=2匹配。此时 case _if ch.toString.equals("3")=> digit=3中_表示忽略得到的值,不去接受 ch。
代码执行结果与分析有出入!没有执行 case_=> sign=2。
分析有一定问题,!执行到了 case _if ch>10 => println("ch >10 ") ,因为!其实是大于10的,
满足条件 case _if ch>10 => println("ch >10 ") ,将 case _if ch>10 => println("ch >10 ") 条件调大,改为 case _if ch>1110 => println("ch >10 "),再次执行结果相同。
注意:
Match 中可以直接用 if 将范围的匹配写在一起,即 Match 既可以对应点的匹配也可以对应范围的匹配。
case_if ch.toString.equals("3")=> digit=3,可以在 if 后面写成范围,如 if (ch>)
for (ch <- "+-3!") 这个字符串遍历过后 ch 是 Char 类型。
在 match 中 case _if ch>1110 => println("ch >10 ") 可以加条件,可以加为case _if (ch>1110&&ch<20) => println("ch >10 ")或 case _if (ch>1110‖ch<120) => println("ch >10 ")
课堂思考题
练习一:
新建命名为 MatchExercise01放入下方代码
for (ch <- "+-3!") {
var sign=0
var digit=0
ch match{
case'+'=> sign=1
case'_'=> sign=-1
//说明..
case_=>digit=3
case_=> sign = 2
}
// + 1 0
// - -1 0
// 3 0 3
// ! 0 3
printin(ch + " " + sign + " "+ digit)
}
首先第一个匹配到+与 case'+'=> sign=1匹配 sign为1,digit没有任何改变仍然为0。
第二个匹配到-与case'_'=> sign=-1匹配 sign为-1,digit没有任何改变仍然为0。
第三个3,3与+匹配不上,与-匹配不上,与 case_=>digit=3匹配 digit为3,sign 没有变为0。匹配上以后会退出不会继续匹配。
第四个!与 case_=>digit=3匹配 digit为3,sign 没有变为0。
执行结果与分析相同这说明在 match 里可以同时写多个。
注意:
ch match{
case'+'=> sign=1
case'_'=> sign=-1
//说明..
case_=>digit=3
case_=> sign = 2
}
这个语法理论上不应该出现,应该报错,case_=> sign = 2 没有机会被执行。
练习二:
有可能以一道面试题和测试题出现
新建命名为 MatchExercise02 放入下方代码
for (ch <- "+-3!") {
var sign=0
var digit = 0
ch match {
case_=> digit=3
case '+' => sign = 1
case '-'=> sign= -1
//说明..
}
println(ch + " " + sign + " " + digit)
}
语法上没有问题
case_=> digit=3是默认条件能全部匹配,case '+' => sign = 1
case '-'=> sign= -1 全都没机会执行。这就将代码的严谨性交给程序员去处理。只要在前面写一个默认,就都能匹配。
如果 case_=> digit=3加入 if 条件,_的含义就发生变化,就不再是默认条件而是忽略传入的 ch 这个词。
将case_=> digit=3改为case_if ch >10000=> digit=3 执行结果抛出一个异常。再加入 case_=>println("没有任何匹配~~~ ")不会抛出异常。