样本类和模式匹配

Posted lyr999736

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了样本类和模式匹配相关的知识,希望对你有一定的参考价值。

一:样本类就是使用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

 

以上是关于样本类和模式匹配的主要内容,如果未能解决你的问题,请参考以下文章

Scala 学习 -- 样例类和模式匹配

Scala 学习 -- 样例类和模式匹配

正则 : 模式

Scala 语言之模式匹配

如何使用模式列表在列中查找字符串并将匹配的模式添加到下一列的同一行

Scala 模式匹配详解