Scala

scala-23-match

2020-04-16  本文已影响0人  chen_666

注意细节

  • 如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中 default 语句
  • 如果所有 case 都不匹配,又没有写 case _ 分支,那么会抛出 MatchError
  • 每个 case 中,不用 break 语句,自动中断 case
  • 可以在 match 中使用其它类型,而不仅仅是字符
  • => 等价于 java swtich 的 :
  • => 后面的代码块到下一个 case, 是作为一个整体执行,可以使用{} 扩起来,也可以不扩。
object MatchDemo01 {
  def main(args: Array[String]): Unit = {
    val oper = '+'
    val n1 = 20
    val n2 = 10
    var res = 0
    oper match {
      case '+' => {
        res = n1 + n2
        println("ok~~")
        println("hello~~")
      }
      case '-' => res = n1 - n2
      case '*' => res = n1 * n2
      case '/' => res = n1 / n2
      case 1 => println("匹配到1")
      case 1.1 => println("匹配1.1")
      case _ => println("oper error")
    }
    println("res=" + res)
  }
}

守卫

如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫

object MatchIfDemo01 {
  def main(args: Array[String]): Unit = {
    for (ch <- "+-3!") { //是对"+-3!" 遍历
      var sign = 0
      var digit = 0
      ch match {
        case '+' => sign = 1
        case '-' => sign = -1
        // 说明..
        // 如果 case 后有 条件守卫即if ,那么这时的 _ 不是表示默认匹配
        // 表示忽略 传入 的 ch
        case _ if ch.toString.equals("3") => digit = 3
        case _ if (ch > 1110 || ch < 120) => println("ch > 10")
        case _ => sign = 2
      }
      //分析
      // + 1 0
      // - -1 0
      // 3 0 3
      // ! 2 0
      println(ch + " " + sign + " " + digit)
    }
  }
}

匹配数组

1)Array(0) 匹配只有一个元素且为 0 的数组。
2)Array(x,y) 匹配数组有两个元素,并将两个元素赋值为 x 和y。当然可以依次类推 Array(x,y,z) 匹配数组有 3 个元素的等等....
3)Array(0,_*) 匹配数组以 0 开始

object MatchArr {
  def main(args: Array[String]): Unit = {

//    val arrs = Array(Array(0), Array(1, 0), Array(0, 1, 0),
//      Array(1, 1, 0), Array(1, 1, 0, 1))
//
//    for (arr <- arrs ) {
//      val result = arr match {
//        case Array(0) => "0"
//        case Array(x, y) => x + "=" + y
//        case Array(0, _*) => "以0开头和数组"
//        case _ => "什么集合都不是"
//      }
//      // result = 0
//      // result = 1 = 0
//      // result = 以0开头和数组
//      // result = 什么集合都不是
//      // result = 什么集合都不是
//      println("result = " + result)
//    }

    //给你一个数组集合,如果该数组时  Array(10,20) , 请使用默认匹配,返回Array(20,10)


    val arrs2 = Array(Array(0), Array(1, 0), Array(0, 1, 0),
      Array(1, 1, 0), Array(1, 1, 0, 1))

    for (arr <- arrs2 ) {
      val result = arr match {
        //case Array(0) => "0"
        case Array(x, y) =>   ArrayBuffer(y,x) //Array(y,x).toBuffer //? ArrayB(y,x)
        //case Array(0, _*) => "以0开头和数组"
        case _ => "不处理~~"
      }

      println("res=" + result) //ArrayBuffer(0,1)
    }

  }
}

匹配变量

object MatchVar {
  def main(args: Array[String]): Unit = {
    val ch = 'U'
    ch match {
      case '+' => println("ok~")
      // 下面 case mychar 含义是 mychar = ch
      case mychar => println("ok~" + mychar)
      case _ => println ("ok~~")
    }

    val ch1 = '+'
    //match是一个表达式,因此可以有返回值
    //返回值就是匹配到的代码块的最后一句话的值
    val res = ch1 match {
      case '+' => ch1 + " hello "
      // 下面 case mychar 含义是 mychar = ch
      case _ => println ("ok~~")
    }

    println("res=" + res)
  }
}

类型匹配

object MatchTypeDemo01 {
  def main(args: Array[String]): Unit = {
    val a = 8
    //说明 obj 实例的类型 根据 a 的值来返回
    val obj = if (a == 1) 1
    else if (a == 2) "2"
    else if (a == 3) BigInt(3)
    else if (a == 4) Map("aa" -> 1)
    else if (a == 5) Map(1 -> "aa")
    else if (a == 6) Array(1, 2, 3)
    else if (a == 7) Array("aa", 1)
    else if (a == 8) Array("aa")

    //说明
    //1. 根据  obj 的类型来匹配
    // 返回值
    val result = obj match {

      case a: Int => a
      case b: Map[String, Int] => "对象是一个字符串-数字的Map集合"
      case c: Map[Int, String] => "对象是一个数字-字符串的Map集合"
      case d: Array[String] => d //"对象是一个字符串数组"
      case e: Array[Int] => "对象是一个数字数组"
      case f: BigInt => Int.MaxValue
      case y: Float => println("xx")
      case _ => "啥也不是"
    }

    println(result)

  }
}

匹配列表

object MatchList {
  def main(args: Array[String]): Unit = {
    for (list <- Array(List(0), List(1, 0), List(88), List(0, 0, 0), List(1, 0, 0))) {
      val result = list match {
        case 0 :: Nil => "0" //
        case x :: y :: Nil => x + " " + y //
        case 0 :: tail => "0 ..." //
        case x :: Nil => x
        case _ => "something else"
      }
      //1. 0
      //2. 1 0
      //3. 0 ...
      //4. something else
      println(result)
    }
  }
}

匹配元组

object MatchTupleDemo01 {
  def main(args: Array[String]): Unit = {
    //如果要匹配 (10, 30) 这样任意两个元素的对偶元组,应该如何写
    for (pair <- Array((0, 1), (1, 0), (10, 30), (1, 1), (1, 0, 2))) {
      val result = pair match { //
        case (0, _) => "0 ..." //
        case (y, 0) => y //
        case (x, y) => (y, x) //"匹配到(x,y)" + x + " " + y
        case _ => "other" //.
      }
      //1. 0 ...
      //2. 1
      //3. other
      //4. other
      println(result)
    }
  }
}

对象匹配

object MatchObject {
  def main(args: Array[String]): Unit = {

    // 模式匹配使用:
    val number: Double = Square(5.0)// 36.0 //

    number match {
      //说明 case Square(n) 的运行的机制
      //1. 当匹配到 case Square(n)
      //2. 调用Square 的 unapply(z: Double),z 的值就是 number
      //3. 如果对象提取器 unapply(z: Double) 返回的是Some(6) ,则表示匹配成功,同时
      //   将6 赋给 Square(n) 的n
      //4.  果对象提取器 unapply(z: Double) 返回的是None ,则表示匹配不成功
      case Square(n) => println("匹配成功 n=" + n)
      case _ => println("nothing matched")
    }


  }
}

//说明

object Square {
  //说明
  //1. unapply方法是对象提取器
  //2. 接收z:Double 类型
  //3. 返回类型是Option[Double]
  //4. 返回的值是 Some(math.sqrt(z)) 返回z的开平方的值,并放入到Some(x)
  def unapply(z: Double): Option[Double] = {
    println("unapply被调用 z 是=" + z)
    Some(math.sqrt(z))
    //None
  }
  def apply(z: Double): Double = z * z
}
object MatchObjectDemo2 {
  def main(args: Array[String]): Unit = {

    val namesString = "Alice,Bob,Thomas" //字符串
    //说明
    namesString match {
      // 当 执行   case Names(first, second, third)
      // 1. 会调用 unapplySeq(str),把 "Alice,Bob,Thomas" 传入给 str
      // 2. 如果 返回的是 Some("Alice","Bob","Thomas"),分别给 (first, second, third)
      //    注意,这里的返回的值的个数需要和 (first, second, third)要一样
      // 3. 如果返回的None ,表示匹配失败

      case Names(first, second, third) => {
        println("the string contains three people's names")
        // 打印字符串
        println(s"$first $second $third")
      }
      case _ => println("nothing matched")
    }

  }
}

//object
object Names {
  //当构造器是多个参数时,就会触发这个对象提取器
  def unapplySeq(str: String): Option[Seq[String]] = {
    if (str.contains(",")) Some(str.split(","))
    else None
  }
}

for表达式中的模式

object MatchForDemo {
  def main(args: Array[String]): Unit = {
    val map = Map("A" -> 1, "B" -> 0, "C" -> 3)
    for ((k, v) <- map) {
      println(k + " -> " + v) // 出来三个key-value ("A"->1), ("B"->0), ("C"->3)
    }
    //说明 : 只遍历出 value =0 的key-value ,其它的过滤掉
    println("--------------(k, 0) <- map-------------------")
    for ((k, 0) <- map) {
      println(k + " --> " + 0)
    }

    //说明, 这个就是上面代码的另外写法, 只是下面的用法灵活和强大
    println("--------------(k, v) <- map if v == 0-------------------")
    for ((k, v) <- map if v >= 1) {
      println(k + " ---> " + v)
    }

  }
}

中置表达式

object MidCase {
  def main(args: Array[String]): Unit = {
    List(1, 3, 5, 9) match { //修改并测试
      //1.两个元素间::叫中置表达式,至少first,second两个匹配才行.
      //2.first 匹配第一个 second 匹配第二个, rest 匹配剩余部分(5,9)
      case first :: second :: rest => println(first + " " + second  + " "+ rest.length + " " + rest) //
      case _ => println("匹配不到...")
    }

  }
}
上一篇 下一篇

猜你喜欢

热点阅读