zoukankan      html  css  js  c++  java
  • scala学习手记39

    在java中有switch/case这样的模式匹配语句,可以匹配的类型包括int,byte,char,short, enum,在java8又支持了字符串。

    在scala中也有类似的模式匹配语句,即match-case。这个好现在之前使用过一次。scala中的match-case匹配的类型更为广泛,它是对Any类型起作用的。

    来看个例子:

    def activity(day: String) {
      day match {
        case "Sunday" => println("Eat, sleep, repeat... ")
        case "Saturday" => println("Hangout with friends... ")
        case "Monday" => println("...code for fun...")
        case "Friday" => println("...read a good book...")
      }
    }
    
    List("Monday", "Sunday", "Saturday").foreach {
      activity
    }

    执行结果:

    image

    有没有注意到,这里和java是有些不一样的,最大的区别是没有break。但是在匹配上了后,也不会继续顺序执行了。其实我一直觉得java的那个switch/case在这一点上是有些不足的,这次总算是在scala中解决了。不过这里也有些让人不爽的地方:比如没有匹配到就会抛出异常。不管怎样,这个异常是不能随意抛出的。在Java的switch/case中,是有一个default来处理那些没有匹配到的内容的。在scala中也有一个特殊的符号起到了类似的作用,就是“_”,这里的下划线是一个通配符。继续修改下上面的代码:

    def activity(day: String) {
      day match {
        case "Sunday" => println("Eat, sleep, repeat... ")
        case "Saturday" => println("Hangout with friends... ")
        case "Monday" => println("...code for fun...")
        case "Friday" => println("...read a good book...")
        case _ => println("...nothing...")
      }
    }
    
    List("Monday", "Sunday", "Saturday", "Tuesday").foreach {
      activity
    }

    就不贴执行结果了。

    需要注意的是:case表达式并不限于在match语句里使用。这里,包含case表达式的代码块就是一个简单函数值。

    刚才说过match-case支持的类型是Any。在java支持的基本类型、枚举和字符串之外,scala也支持其他任意类型的实例,比如列表和元组:

    def processCoordinates(input: Any) {
      input match {
        case (a, b) => printf("Processing (%d, %d)... ", a, b)
        case List("red", "blue", "white") => println("Stars and Stripes...")
        case List("red", "blue", _*) => println("colors red, blue, ... ")
        case "done" => println("done")
        case _ => null
      }
    }
    processCoordinates((39, -104))
    processCoordinates("done")
    processCoordinates(List("red", "blue", "green"))
    processCoordinates (List("red", "blue", "white"))

    看下执行结果:

    image

    前面有一段警告,可以不去管它。

    不过代码里却是有些不足之处,其中对元组的匹配还可以更细致些,比如针对不同类型的值可以做不同的处理:

    def process(input: Any) {
      input match {
      case (a: Int, b: Int) => print("Processing (int, int)... ") -
      case (a: Double, b: Double) => print("Processing (double, double)... ")
      case msg: Int if (msg > 1000000) => println("Processing int > 1000000")
      case msg: Int => print("Processing int... ")
      case msg: String => println("Processing string... ") -
      case _ => printf("Can't handle %s... ", input)
      }
    }
    
    process ((34.2, -159.3))
    process(0)
    process(1000001)
    process (2.2)

    代码中演示了在case语句里如何为单一的值和元组元素指定类型。除了类型之外,还可以使用卫述句(guard)。卫述句用if从句表示,在模式匹配里,对表达式求值前必须满足卫述句。

    看下结果:

    image

    case的顺序很重要。Scala会自上而下地求值。所以,上面代码5和6两行是不能交换的。

    ##########

  • 相关阅读:
    求解整数集合的交集(腾讯笔试)
    关于屏幕适配之比例布局
    (转)注册JNI函数的两种方式
    正则表达式记录
    当年一个简单可用的多线程断点续传类
    最近用到的几个工具方法
    Android中包含List成员变量的Parcel以及Parcel嵌套写法示例
    java实现计算MD5
    一个用于去除状态栏和虚拟导航栏的BaseActivity
    MVP的模板
  • 原文地址:https://www.cnblogs.com/amunote/p/5880007.html
Copyright © 2011-2022 走看看