scala模式匹配04
模式匹配是Scala中非常强大的一种功能。模式匹配,其实类似于Java中的switch case语法,即对一个值进行条件判断,然后针对不同的输入条件,进行结果处理。
1.可以用到Switch语句中
var sign = 0
val ch = '+'
sign = ch match {
case '-' => -1
case '*' => -2
case '+' => 0
case _ => 1
}
println("sign=" + sign)
2.守卫
def caseOps2: Unit = {
println("请输入任意字符:")
val ch = StdIn.readChar()
val sign = ch match {
case '+' => 2
case '-' => 3
case '*' => 4
case '/' => 5
case _ => 0
}
println("sign=" + sign)
}
3. 模式中的变量和类型模式
类型
def typeOps: Unit = {
class Person(name:String, age:Int) {
}
class Worker(name:String, age:Int) extends Person(name, age) {
def work(): Unit = {
println(s"工人同志${name}, 年龄为${age}正在热火朝天的休息~")
}
}
class Student(name:String, age:Int) extends Person(name, age) {
def study(): Unit = {
println(s"学生${name}, 年龄为${age}正在紧锣密鼓的玩游戏~")
}
}
def doSth(p:Person): Unit = {
p match {
//java中的Worker w = (Worker)p;
case w: Worker => w.work()
case s: Student => s.study()
case _ => println("类型不匹配")
}
}
doSth(new Worker("韦启蒙", 35))
4. 匹配数组、列表和元组
数组
val array = Array(0, -5)
array match {
//匹配数组有2个元素,分别将两个元素赋值给x和y
case Array(x, y) => println(s"x=$x, y=$y")
//匹配数组以0开头
case Array(0, _*) => println("Array(0, _*)")
//默认的匹配,如果匹配不到,scala.MatchError
case _ => println("default")
}
对元组的匹配
val ret = lines
.flatMap(_.split("\\s+"))
.groupBy(word => word)
.map{case (key, values) => (key, values.length)}
5. 样例类
所谓样例类,就是case class,是scala中一种专门用来携带数据的class,类似于java中的javabean,一般的定义方式需要定义该case class的主构造器,其所有的字段都在主构造器中完成声明,case class自动会提供所谓getter和setter方法。
case class的主构造函数接收的参数通常不需要使用var或val修饰,Scala自动就会使用val修饰(但是如果你自己使用var修饰,那么还是会按照var来)
Scala自动为case class定义了伴生对象,也就是object,并且定义了apply()方法,该方法接收主构造函数中相同的参数,并返回case class对象
def caseOps6: Unit = {
abstract class Expr //抽象类 表达式
case class Var(name:String) extends Expr
case class UnOp(expr:Expr, operator:String) extends Expr
case class Number(num:Double) extends Expr
case class BinOp(left:Expr, operator:String, right:Expr) extends Expr
def test(expr:Expr) = {
expr match {
case Var(name) => println("Var: " + name)
case Number(num) => println("Number: " + num)
case UnOp(Var(name), "+") => println(name + "+")
case BinOp(Number(num1), "+", Number(num2)) => println(num1 + num2)
case BinOp(Number(num1), "-", Number(num2)) => println(num1 - num2)
case BinOp(Number(num1), "*", Number(num2)) => println(num1 * num2)
case _ => println(expr)
}
}
test(BinOp(Number(3.0), "-", Number(5.2)))
}
6.模拟枚举
sealed class密封类,一个类的所有的子类型都是已知的,都必须要在定义期间给出
当然一般这个sealed class密封类通常会被声明为抽象,使用子类来完成具体构建
密封类的所有子类都必须在与该密封类相同的文件中定义。
如果某个类是密封的,那么在编译期所有的子类是可知的,因而可以检查模式语句的完整性。
让所有同一组的样例类都扩展某个密封的类或特质是个好的做法。
sealed abstract class TrafficLight(color:String)
case class RED(red:String) extends TrafficLight(red)
case class GREEN(green:String) extends TrafficLight(green)
case class YELLOW(yellow:String) extends TrafficLight(yellow)
val light:TrafficLight = RED("酒后来驾车,亲人泪两行")
light match {
case RED(red) => println(red)
case GREEN(green) => println(green)
case YELLOW(yellow) => println(yellow)
}
7.Option
Option是scala中有值(Some)或者没有值(None)的类型,scala也可以对应Option进行模式匹配进行处理。
val map = Map[String, String](
"China" -> "BJ",
"India" -> "XDL",
"Japan" -> "Tokyo"
)
map.get("India") match {
case Some(capital) => println("India's capital is " + capital)
case None => println("所查国家不存在")
}
8.偏函数
被包在花括号内没有match的一组case语句是一个偏函数,它是PartialFunction[A, B]的一个实例,A代表参数类型,B代表返回类型,常用作输入模式匹配
//偏函数
object PartialFuncDemo {
def func1: PartialFunction[String, Int] = {
case "one" => 1
case "two" => 2
case _ => -1
}
//普通模式匹配
def func2(num: String) : Int = num match {
case "one" => 1
case "two" => 2
case _ => -1
}
def main(args: Array[String]) {
println(func1("one"))
println(func2("one"))
}
}
上一篇: 番茄鱼的做法大全具体做法
下一篇: Scala样例类