Scala 取消应用方法

标签 scala pattern-matching unapply

我想了解 scala unapply 方法。

以下是我的理解。假设我有一个 Person 对象:

class Person(val fname: String, val lname: String)

object Person{
  def unapply(x: Person) : Option[(String, String)] = 
    Some(x.fname,x.lname)
}

new Person("Magic", "Mike") match {
  case Person(x, y) => s"Last Name is ${y}"
  case _ => "Unknown"
}

我假设这个案例调用了类似的东西:

val temp = Person.unapply(new Person("Magic", "Mike"))
if (temp != None)  { val (x, y) = temp.get }
else { <go to next case> }

但是当我有如下情况时,下面的取消应用是如何工作的:

new Person("Magic", "Mike") match {
  case Person("Harold", y) => s"Last Name is ${y}"
  case Person("Magic", y) => s"Last Name is ${y}"
  case _ => "Unknown"
}

它如何在 unapply 方法中访问 fname("Magic") 的值并给我与第一个相同/正确的结果?

最佳答案

使用 -Xprint:patmat 运行 scalac 将向您展示句法树在模式匹配阶段后的样子:

scalac -Xprint:patmat test.scala

  case <synthetic> val x1: Person = new Person("Magic", "Mike");
  case10(){
    <synthetic> val o12: Option[(String, String)] = Person.unapply(x1);
    if (o12.isEmpty.unary_!)
      {
        <synthetic> val p3: String = o12.get._1;
        val y: String = o12.get._2;
        if ("Harold".==(p3))
          matchEnd9(scala.StringContext.apply("Last Name is ", "").s(y))
        else
          case11()
      }
    else
      case11()
  };
  case11(){
    <synthetic> val o14: Option[(String, String)] = Person.unapply(x1);
    if (o14.isEmpty.unary_!)
      {
        <synthetic> val p5: String = o14.get._1;
        val y: String = o14.get._2;
        if ("Magic".==(p5))
          matchEnd9(scala.StringContext.apply("Last Name is ", "").s(y))
        else
          case13()
      }
    else
      case13()
  };
  case13(){
    matchEnd9("Unknown")
  };

如您所见,对于每种情况,它首先在匹配的对象上调用 unapply,然后如果 Option 不为空(因此匹配),它会检查是否元组的元素之一等于预期值,如果是,则它与这种情况的闭包匹配。

关于Scala 取消应用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41334239/

相关文章:

scala - 理解不适用没有案例类

scala specs2 错误 : anon is not equal scala. collection.immutable

scala - 在 Scala 中执行字符串条件连接的最惯用的方法

haskell - 在 Haskell 中合并多个案例

r - R 中有类似 Rust 模式语法的东西吗?

mysql - SQL字符串匹配

scala - 在 Scala Play 应用程序中避免此 java.lang.ClassCastException 错误的正确应用和取消应用方法是什么?

scala - 如何使用类型标签/镜像在方法中获取构造函数参数?

scala - 查找当前正在运行的 SparkContext 的名称

scala - 如何在多态 unapply 中使用提取器?