样本类和模式匹配

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

 

posted @ 2019-08-18 18:03 Coding_Now 阅读(...) 评论(...) 编辑 收藏