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"))
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值