欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

scala模式匹配04

程序员文章站 2022-06-14 16:54:28
...

模式匹配是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"))
  }
}