53_模式匹配

/*
* 语法
* 目标值 match {
* case 条件1 => 操作1
* case 条件2 => 操作2
* case 条件3 => 操作3
* case 条件4 => 操作4
* case _ => 操作5
* }
* 返回值 操作对应的结果
* 说明
* 1.都匹配不上时,会进入_分支,如果没有_分支,会报错MatchError
* 2.每个case分支中,不需要使用break,在满足的条件分支下停止,不会有穿透
* 3.目标值可以匹配任何类型,不只是字面量
* 4.=>后面是代码块,可以使用 {}
*
* 模式守卫
* 匹配范围,match的case语句中可以定义变量
*
* 通配符
* 1. _ 单元素通配符 / else通配符
* 2. _* 多元素通配符
* 3. x,y(任意变量名称) 单元素通配符
*
* 匹配类型
* 1. 匹配常量 常量类型可以是 字符串、字符、数字、布尔值等
* 2. 匹配数据类型
* 说明
* 1. 判断变量类型 可以使用 obj.isInstanceOf[dataType]
* 泛型擦除
* 泛型只在编译器有效,运行期会去掉(数组除外)
* 3. 匹配数组
* 判断数组元素个数、及数组元素的值
* 4. 匹配列表
* 判断啥样类型Array
* 5. 匹配元组
* 扩展使用
* 1. 为多个变量赋值
* 2. for推导式中使用变量
* 6. 匹配对象
* 必须实现unapply方法
*
* 样例类
* 语法
* case class ClassName
* 作用
* 默认实现 伴生类及 apply和unapply方法
* 类参数默认为 类成员属性
*
* */
/*
* 语法
*   目标值 match {
*       case 条件1 => 操作1
*       case 条件2 => 操作2
*       case 条件3 => 操作3
*       case 条件4 => 操作4
*       case _    => 操作5
*   }
*   返回值 操作对应的结果
*   说明
*      1.都匹配不上时,会进入_分支,如果没有_分支,会报错MatchError
*      2.每个case分支中,不需要使用break,在满足的条件分支下停止,不会有穿透
*      3.目标值可以匹配任何类型,不只是字面量
*      4.=>后面是代码块,可以使用 {}
*
*  模式守卫
*    匹配范围,match的case语句中可以定义变量
*
*  通配符
*     1. _ 单元素通配符 / else通配符
*     2. _* 多元素通配符
*     3. x,y(任意变量名称) 单元素通配符
*
*  匹配类型
*       1. 匹配常量 常量类型可以是 字符串、字符、数字、布尔值等
*       2. 匹配数据类型
*          说明
*             1. 判断变量类型 可以使用 obj.isInstanceOf[dataType]
*          泛型擦除
*             泛型只在编译器有效,运行期会去掉(数组除外)
*       3. 匹配数组
*             判断数组元素个数、及数组元素的值
*       4. 匹配列表
*             判断啥样类型Array
*       5. 匹配元组
*             扩展使用
*                 1. 为多个变量赋值
*                 2. for推导式中使用变量
*       6. 匹配对象
*             必须实现unapply方法
*
*  样例类
*     语法
*        case class ClassName
*     作用
*         默认实现 伴生类及 apply和unapply方法
*         类参数默认为 类成员属性
*
* */
//基础语法
object MatchTest extends App {
  var a = 3
  var b = 2
  var op = '.'
  var result = op match {
    case '+' => a + b
    case '-' => a - b
    case '*' => a * b
    case '/' => a / b
    case _ => "非法操作符"
  }
  println(result)

}

//模式守卫
object MatchIf extends App {
  //模式守卫
  //会把目标值x 赋值给i
  def abs(x: Int) = {
    x match {
      case i: Int if i >= 0 => i
      case a: Int if a < 0 => -a
      case _ => "非法目标值"
    }
  }

  println(abs(-10))

}

//匹配字面量
object MatchConst extends App {
  //匹配常量
  def desc(x: Any) = x match {
    case 'x' => println(x.getClass)
    case "str" => println(x.getClass)
    case 1 => println(x.getClass)
    case 1.1 => println(x.getClass)
    case _ => println(x.getClass)
  }

  desc(1)
}

//匹配数据类型 + 泛型擦除
object MatchDataType extends App {
  //匹配类型
  var list: List[Int] = List(1, 2, 3, 4, 5, 6)
  var arr: Array[Int] = Array(1, 2, 3, 4, 5, 6)
  var str = "字符串"
  //判断数据类型
  println(list.isInstanceOf[List[String]]) //判断变量类型
  println(arr.isInstanceOf[Array[String]]) //判断变量类型

  def showDataType(data: Any) = data match {
    case i: Int => println("Int")
    case s: String => println("String")
    case l: List[String] => println("List[Int]")
    case a: Array[Int] => println("Array[Int]")
    case other => println("other")
  }

  showDataType(list) //运行期间会将list的泛型擦除的,不会判断list的泛型
}

//匹配数组
object MatchArray extends App {
  //初始化
  var arr = Array(
    Array(0), Array(1), Array(3)
    , Array(1, 2), Array(2, 3), Array(4, 5)
    , Array(1, 2, 3)
    , Array("dawang", 90)
  )
  //遍历
  for (e <- arr) {
    var result = e match {
      case Array(0) => "等于Array(0)" // 匹配Array(0)
      case Array(x, y) => s"${x} : ${y}" //匹配Array(x,y)
      case Array(0, _*) => "0开头的数组"
      case _ => "other"
    }
    println(result)
  }


}

//匹配链表
object MatchList extends App {
  //初始化
  var list = List(
    List(0), List(1), List(2)
    , List(1, 2)
    , List(1, 2, 3)
    , List(1, "大王", 3)
  )
  //遍历
  for (e <- list) {
    //match每个元素e
    var result = e match {
      case List(x) => "match只有一个元素的list"
      case List(1, 2) => "match-List(1, 2)的list"
      case List(_, _, _) => "match-三个元素的list"
      case _ => "other"
    }
    println(result)
  }
  println("==================")
  //方式二
  var list2 = List(1, 2, 3, 4, 5)
  list2 match {
    case first :: second :: rest => println(s"${first} - ${second} -${rest}")
    case _ => println("其他")
  }


}

//匹配元组
object MatchTuple extends App {
  //初始化
  var tuple = Array(
    (0, 1), (1, 2, 3), (2, 2, 1), (2, 2, 2),
    (1, 2, 3, 4), (2, 2)
  )
  //遍历
  for (e <- tuple) {
    var result = e match {
      case (_, _) => "二元元组"
      case (_, _, _) => "三元元组"
      case (_, _, _, _) => "四元元组"
      case _ => "other"

    }
    println(result)
  }

}

//为多个变量赋值
object MatchMultiVal extends App {
  //1. 声明多个变量(使用元组)
  var (x, y) = (10, "大王")
  println(s"${x} - ${y}")
  //2. 声明多个变量(使用链表)
  var List(id, name, age) = List(1, "黎明", 20)
  println(s"${id} - ${name} - ${age}")
  //3. 声明多个变量(使用链表2)
  var f1 :: f2 :: f3 = List(1, 2, 3, 4, 5)
  println(s"${f1} - ${f2} - ${f3}")

}

//for推导式中使用变量
object MatchForVal extends App {
  //初始化list
  var list = List(("word", 2), ("key", 3), ("word", 4), ("dawang", 2), ("reduce", 2), ("word", 2))

  //1.普通遍历
  for (e <- list) {
    println(s"${e._1} - ${e._2}")
  }
  println("==============")
  //2.接收变量为元组
  for ((word, key) <- list) {
    println(s"${word} - ${key}")
  }
  println("==========")
  //3.接收变量为元组,且指定某个位置的值
  for (("word", key) <- list) {
    println(s"word - ${key}")
  }

}

//匹配对象
object MatchObject extends App {
  //创建 Person实例
  var per = new Person(18, "dawang")
  //判断 实例属性值
  per match {
    case Person(19, "dawang") => println("这个是")
    case _ => println("这不是")
  }
  //创建样例类实例
  var std = Student(1, "张")
  //模式匹配(证明李明是不是李明)
  std match {
    case Student(1, "李明") => println("这是李明")
    case Student(1, "张三") => println("这是张三")
    case _ => println("这不是张三也不是李明")
  }

}

object Person {
  def apply(age: Int, name: String): Person = new Person(age, name)

  def unapply(per: Person): Option[(Int, String)] = {
    if (per == null)
      None
    else
      Some(per.age, per.name)

  }
}

class Person(var age: Int, var name: String)

//定义样例类
case class Student(id: Int, name: String)

 

上一篇:剑指 Offer 53 - I. 在排序数组中查找数字 I


下一篇:GoJS v2.1.53 使用以及去除水印办法