Scala模式匹配(下篇):高级特性

44 阅读2分钟

六、样例类匹配与面向对象设计

案例:几何图形面积计算

package matchcase

object case06 {
  /*
  * match case
  *  1,匹配元组不同的元素的数量
  *  2. 匹配数值特殊值
  *  3. 匹配变量的类型
  *  5. 匹配样例类
  */

  // 1. 圆形类
  case class Circle(radius: Double) {}

  // 2. 矩形类
  case class Rectangle(width: Double, height: Double) {}

  // 封装一个求面积的方法
  def getArea(shape: Any): Double = {
    shape match {
      case Circle(radius) => math.Pi * radius * radius
      case Rectangle(width, height) => width * height
      case _ => 0.0
    }
  }

  def main(args: Array[String]): Unit = {
    // 1. 实例化圆形对象
    val circle = Circle(2.0)
    // 2. 实例化矩形对象
    val rectangle = Rectangle(2.0, 3.0)
    // 3. 调用求面积的方法
    println(getArea(circle))
    println(getArea(rectangle))
  }
}

运行结果

66.png

代码分析

样例类定义

  1. case class Circle(radius: Double) 定义圆形样例类
  2. case class Rectangle(width: Double, height: Double) 定义矩形样例类
  3. 样例类自动获得:equals/hashCode方法、toString方法、copy方法、伴生对象apply/unapply方法

七、守卫语句与复杂条件匹配

7.1 守卫语句基本格式

value match {
    case pattern if guardCondition => result
    // 其他case语句...
}

八、for表达式中的模式匹配

8.1 Map数据过滤与提取

案例:从企业家数据中筛选特定年份出生的人

package matchcase

object case07 {
  def main(args: Array[String]): Unit = {
    val m1 = Map(
      "马云 - 阿里巴巴" -> 1964,
      "马化腾 - 腾讯" -> 1971,
      "李彦宏 - 百度" -> 1968,
      "雷军 - 小米" -> 1969,
      "丁磊 - 网易" -> 1971,
      "张一鸣 - 字节跳动" -> 1983,
      "刘强东 - 京东" -> 1974,
      "程维 - 滴滴" -> 1983,
      "王兴 - 美团" -> 1979,
      "周鸿祎 - 360" -> 1970,
      "黄峥 - 拼多多" -> 1980,
      "李想 - 理想汽车" -> 1981,
      "何小鹏 - 小鹏汽车" -> 1977,
      "贾跃亭 - 乐视" -> 1973,
      "陈天桥 - 盛大网络" -> 1973,
      "周源 - 知乎" -> 1980,
      "王小川 - 搜狗" -> 1978
    )
    
    // 方式1:使用模式匹配直接过滤
    println("=== 1983年出生的企业家(模式匹配方式)===")
    for((key, 1983) <- m1) {
      println(key)
    }
    
    // 方式2:传统if守卫方式
    println("\n=== 1983年出生的企业家(if守卫方式)===")
    for ((key, value) <- m1) {
      if (value == 1983)
        println(key)
    }
  }
}

运行结果

77.png

代码分析

模式匹配方式

  1. for((key, 1983) <- m1) 直接在for循环中进行模式匹配
  2. 只遍历Map中值为1983的键值对
  3. 语法简洁,意图明确,无需额外if条件

传统if守卫方式

  1. for ((key, value) <- m1) 遍历所有元素
  2. if (value == 1983) 在循环体内进行条件判断
  3. 需要临时变量value,代码稍显冗长