case-class上的`productElement(i)`是否使用反射?

考虑以下 Scala片段:

case class Foo(v1: String,v2: Int,v3: Any)

def inspect(p: Product) =
  (0 until p.productArity).foreach(i => println(p.productElement(i)))

inspect(Foo("Moin",77,null))

在这里调用inspect()是否意味着使用反射(以任何方式)?

我想以某种方式能够访问案例类的字段而不必明确地引用它们,例如通过foo.v1,我赞成一个不需要反射的解决方案,因为我希望它需要一些开销.

解决方法

productElement不会使用反射.这是一个编译技巧.在类之前添加大小写不只是创建一个伴随对象(使用apply方法等,参见 http://www.scala-lang.org/node/258),它还从特征Product扩展了类.编译器创建抽象方法productArity和productElement的实现.

scalac -print Foo.scala的输出显示

... case class Foo extends java.lang.Object with ScalaObject with Product {
...
override def productArity(): Int = 3;
override def productElement(x$1: Int): java.lang.Object = {
  <synthetic> val temp6: Int = x$1;
  (temp6: Int) match {
    case 0 => {
      Foo.this.v1()
    }
    case 1 => {
      scala.Int.Box(Foo.this.v2())
    }
    case 2 => {
      Foo.this.v3()
    }
    case _ => {
      throw new java.lang.indexoutofboundsexception(scala.Int.Box(x$1).toString())
    }
  }
};
...
}

如果要访问没有反射的字段,可以使用特征产品中的方法productElement

scala> case class Foo(v1: String,v3: Any)
defined class Foo

scala> val bar = Foo("Moin",null)
bar: Foo = Foo(Moin,null)

scala> bar.productElement(0)
res4: Any = Moin

scala> bar.productElement(1)
res5: Any = 77

scala> bar.productElement(2)
res6: Any = null

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...