一:样本类就是使用case关键字声明的类,和普通类的用法都一致。
package 样本类和模式匹配 /** * @Author:Alex_lei * @Description: */ object Case_class { /** * people就是样本类 * @param name 名字属性 * @param age 年龄属性 */ case class people(name:String,age:Int) def main(args: Array[String]): Unit = { val p1 = people("alex",23) val p2 = people("Lily",22) println(p1) } }
二:模式匹配
模式分为:通配符,常量模式,变量模式,构造器模式,序列模式,元组模式,类型模式。
代码示例:
package 样本类和模式匹配 import math.{E, Pi} /** * @Author:Alex_lei * @Description: 几种模式的种类 */ object Mode { case class people(name:String,age:Int) def main(args: Array[String]): Unit = { /** * 测试通配符 */ catch_all(3) println(describe(5)) /** * 3.变量模式,在此例子中,pi是变量模式,所以它可以匹配任意值,所以后续的值不会匹配。 */ val pi = Pi val res = E match { case pi => "pi" case _ => "OK" } println(res) /** * 测试构造器模式 */ val p = people("alex",22) Constructor_mode(p) /** * 5.序列模式,匹配如List或Array这样的类型 */ val l = List(1,2,3) l match { case List(_,_,_) => println("list") case _ => println("something else") } /** * 6.元组模式 */ val t = (1,"alex",22) t match { case (_,_,_) => println("tuple") case _ => println("something else") } /** * 测试类型模式 */ val s = "alex" type_mode(s) val m = Map(1->'2',2->'3') type_mode(m) val m1 = Map("alex" -> "name","Lily" -> "name1") println(show(m1 get "alex")) } /** * 1.通配符,符号:_ 可以匹配任何对象 */ def catch_all(a:Int): Unit = { a match { case 1 => println('a') case 2 => println('c') case _ => println('_') } } /** * 2.常量模式:用常量去匹配,基本类型的常量和val或单例对象也可以被用作常量。 * @param x */ def describe(x:Any) ={ x match { case 5 => "five" case true => "truth" case "hello" => "hi" case Nil => "the empty list" case _=> "something else" } } /** * 4.构造器模式 * @param p */ def Constructor_mode(p:people) = { p match { case people(_,_) => println("people") case _ => println("any") } } /** * 7.类型模式 * @param x */ def type_mode(x:Any) = { x match { case s: String => println(s.length) case m: Map[_,_] => println(m.size) case _ => println("something else") } } def show(x:Option[String]) = x match { case Some(s) => s case None => "?" } }
三:模式守卫
作用:主要是为了更精确的匹配模式,主要就是在匹配的时候加一些过滤条件。
代码示例:
package 样本类和模式匹配 /** * @Author:Alex_lei * @Description: 模式守卫,主要是为了更精确的匹配模式 */ object Mode_guard { def main(args: Array[String]): Unit = { /** * 测试模式守卫 */ val a = -10 print("a = -10 :") m(a) val b = 10 print("b = 10 :") m(b) val s = "abc" print("s = abc :") m(s) val t = "a" print("t = a :") m(t) } def m(x:Any) = x match { case x:Int if x>0 => println("Int") case x:String if x.length>2 => println("String") case _ => println("Any") } }
四:Option类型
option类型的值只有两种形式,可以是Some(x),其中x是实际值,也可以None对象,Some和None都是它的子类,都是使用final修饰,不能再有派生子类。
代码示例:
package 样本类和模式匹配 /** * @Author:Alex_lei * @Description: option类型的值只有两种形式,可以是Some(x),其中x是实际值,也可以None对象 * Some和None都是它的子类,都是使用final修饰,不能再有派生子类 */ object Option { def main(args: Array[String]): Unit = { val book = Map("Hadoop" -> 10,"Spark" -> 20,"Flink" -> 30,"Scala" -> 40) val t = book.get("Hadoop") //Option[Int] = Some(10)返回值是Option[Int]类型 println(t) /** * 下面两个例子说明,当有返回值的时候,结果不会返回getOrElse的参数 * 当没有返回值的时候,结果就会返回getOrElse的参数 */ val t1 = book.get("Hbase").getOrElse("No key") //No key println(t1) val t2 = book.get("Spark").getOrElse("yes") //20 println(t2) } }
五:封闭类
封闭类,使用sealed关键字,用于模式匹配,当我们用样本类来做模式匹配时,想让编译器帮助我们确保列出了所有的可能,我们需要将样本类的超类进行封闭。但是在进行模式匹配的时候,必须要在匹配的表达式后面加一个@unchecked注解,功能是对于随后的模式的穷举性检查将被抑制掉。否在会出现警告。
代码示例:
package 样本类和模式匹配 /** * @Author:Alex_lei * @Description: 封闭类,使用sealed关键字,用于模式匹配,当我们用 * 样本类来做模式匹配时,想让编译器帮助我们确保列出了所有 * 的可能,我们需要将样本类的超类进行封闭。 */ object Sealed { def main(args: Array[String]): Unit = { val t = Number(2) val res = describe(t) println(res) des(t) desc(t) } /** * Warning:(16, 33) match may not be exhaustive. * It would fail on the following inputs: Binop(_, _, _), Unop(_, _) * def describe(x:Expr):String = x match { * * 这样写,会出现警告,说还有两种可能性 * * 解决方式可以有以下两种,分别为des函数和desc函数 * des函数主要是在加一个通配符 * desc函数是在要匹配的表达式后面加一个@unchecked注解,功能是对于随后的模式的穷举性检查将被抑制掉 */ def describe(x:Expr):String = x match { case Number(_) => "a number" case Var(_) => "a string" } def des(x:Expr):String = x match { case Number(_) => "a number" case Var(_) => "a string" case _ => throw new RuntimeException } def desc(x:Expr):String = (x: @unchecked) match { case Number(_) => "a number" case Var(_) => "a string" } } /** * 定义封闭类Expr */ sealed abstract class Expr /** * 定义四个样本类继承Expr * */ case class Var(name:String) extends Expr case class Number(num:Double) extends Expr case class Unop(operator:String,args:Expr) extends Expr case class Binop(operator:String,left:Expr,right: Expr) extends Expr