Scala模式匹配

模式匹配指检查某个值(value)是否匹配某一个模式的机制,是 Scala 非常重要、非常强大的功能,它不仅可以匹配值,还能够匹配类型等。其本质是 match case 语法
1.match表达式
(1)定义:
①类似 Java 中的 switch 语句
②Scala中任何类型都能当作比较用的样本(case),另外每个备选项最后不需要 break
③break 是隐含的,防止因为疏忽从一个选择落入另一个中
(2)match选择器

val firstArg=if(args.length>0) args(0) else ""
firstArg match{
 case "salt" => println("pepper")
 case "chips" => println("salsa")
 case "eggs" => println("bacon")
 case _ => println("huh?") //以上未列出的值,使用“_”表示
}
println(friend)

2.模式的种类
(1)通配模式
①定义:
通配模式(_)匹配任意对象,即全匹配。应该保证最少一个模式匹配

expr match {
 case 1=>println("one")
 case 2=>println("two")
 case _=>
}

②通配模式还可以用来忽略对象中不关心的部分。

(1,2) match {
 case (x,_)=>println(x) //不关心第二个元素
}

(2)常量模式
常量模式仅匹配自身,任何字面量都可用做常量。

def describe(x:Any)=x match{
 case 5=>"five"
 case true=>"truth"
 case "hello"=>"hi!"
 case Nil=>"the empty list"
 case _=>"something else"
}

(3)变量模式
①类似于通配模式,可以匹配任意对象。

val expr=10
expr match {
 case 0=>println("zero")
 case x=>println(x) //变量模式
}

②以小写字母开头的名称为变量模式,其它均为常量模式

import scala.math.{E,Pi}
E match {
 case Pi=>println(Pi) //常量模式
 case _=>println("others")
}
//输出:others

③如果常量符号也是小写字母开头,则需要使用反引号括起来“常量符号”。

import scala.math.E
val i=1.2
E match {
 case `i`=>println(i) //强制常量模式
 case _=>println("others")
}
//输出:others

(4)构造器模式
①构造器模式检查对象是否为该名称的样本类实例,并提取构造参数绑定到指定变量中。

case class Student(name:String,age:Int)
//样例类的模式匹配
def matchTest4(x: Student)= x match {
 case Student(name,19) => println(name)
 case Student("Tom",age) => println(age)
 case Student(name,age) => println(name,age)
 case _ => println("no matches")
}
matchTest4(Student("Jason",19))
matchTest4(Student("Tom",20))
matchTest4(Student("Jimmy",20))

②样例类中,自动实现了 unapply()方法(也称提取器),用于将对象分解为用以匹配模式的片段,即该方法接受一个实例对象,返回最初创建它所用的参数。
对于普通类也可以使用模式匹配,前提是实现了提取器。

class Student(_name:String,_age:Int) {
 var name=_name
 var age=_age
}
object Student{ 
 def unapply(arg: Student): Option[(String, Int)] ={
 if(arg==null) None else Some(arg.name,arg.age) //实现提取器
 } }
def matchTest(x:Student)=x match {
 //应用提取器 Student.unapply(x)
 case Student(n,a) => println(n,a) 
}
matchTest(new Student("Jason",19)) //输出:(Jason,19)

(3)提取器返回的是 Option 类型,该类型有两种形式
①None:表示无值
②Some(x):表示有值,x 是实际值
Some 和 Node 均是 Option 的子类。

(5)序列模式
与样本类类似,序列类型也可以用于模式匹配。

val expr=List(1,2,3)
expr match {
 case List(x,_,_)=>println(x)
 case _=>println("not found")
}
expr match {
 case List(1,_*)=>println("found it") //_*作为模式的最后元素
 case _=>println("not found")
}

(6)元组模式

val expr=(1,2,3)
expr match {
 case (a,b,c)=>println(a,b,c)
 case _=>println("not found")
}

(7)类型模式

def matchTest3(x: Any): String = x match {
 case x:Int => "Int"
 case x:String => "String"
 case _ => "Any"
}
matchTest3(3.0) // Any
matchTest3(1) // Int

(8)变量绑定
格式:变量名 @ 部分模式

val expr=List(1,2,3)
expr match {
 case List(x,tail @ _*)=>println(x,tail)
 case _=>println("not found")
}
//输出:(1,List(2, 3))

(9)模式守卫
模式守卫与 for 循环守卫用法类似,用于限制模式的匹配规则。守卫可以是引用模式中的任意布尔表达式,如果有守卫,只有在守卫返回
true 时才匹配成功

def matchTest2(x: Int): String = x match {
 case i if i==1 => "one"
 case i if i==2 => "two"
 case _ => "many"
}
matchTest2(3) // many
matchTest2(1) // one
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值