首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解Case类的“unapply”

理解Case类的“unapply”
EN

Stack Overflow用户
提问于 2016-05-20 10:44:23
回答 1查看 529关注 0票数 3

在下面的代码中,我试图理解Foo#unapply : Option[Int]在模式匹配方面的用法。

代码语言:javascript
复制
$ls
Test.scala
$cat Test.scala 
object Test {

  case class Foo(x: Int)

  def f(foo: Foo): Unit = foo match {
    case Foo(_) => ()
  }

}

它编译:

代码语言:javascript
复制
$scalac Test.scala 
$ls
Test$.class Test$Foo$.class Test$Foo.class  Test.class  Test.scala

我对每个*class文件运行了javap -c -v X.class | grep unapply。但是,我没有找到任何结果。

请解释一下Foo#unapply是如何用于模式匹配的。另外,我在哪里可以找到相应的JVM字节码指令?

EN

回答 1

Stack Overflow用户

发布于 2016-05-20 17:52:12

如果使用-Xprint:typer-print进行编译,您将看到生成的代码。这是用scalac -Xprint:typer Test.scala编译的经过清理的applyunapply版本

代码语言:javascript
复制
case def apply(x: Int): com.yuval.Test.Foo = new Foo(x);
case def unapply(x$0: com.yuval.Test.Foo): Option[Int] = if (x$0.==(null))
    scala.this.None
  else
    Some.apply[Int](x$0.x);

f保持不变:

代码语言:javascript
复制
def f(foo: com.yuval.Test.Foo): Unit = foo match {
  case (x: Int)com.yuval.Test.Foo(_) => ()
}

这是来自Test$.class的Java反编译代码

代码语言:javascript
复制
public void f(Test.Foo foo) {
    Test.Foo localFoo = foo;
    if (localFoo != null) {
        BoxedUnit localBoxedUnit = BoxedUnit.UNIT;
    } else {
        throw new MatchError(localFoo);
    }
}

这是用java -c -p Test$.class生成的字节码

代码语言:javascript
复制
public void f(com.yuval.Test$Foo);
  Code:
   0: aload_1
   1: astore_2
   2: aload_2
   3: ifnull        11
   6: getstatic     #20    // Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
   9: astore_3
  10: return
  11: new           #22    // class scala/MatchError
  14: dup
  15: aload_2
  16: invokespecial #25    // Method scala/MatchError."<init>":(Ljava/lang/Object;)V
  19: athrow

这里的模式匹配变成了一个简单的类型检查。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37337135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档