Scala模式匹配

it2024-10-27  42

模式匹配指检查某个值(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)