caseElass(i)`case-class是否使用反射?
问题描述:
考虑下面的Scala代码片段:caseElass(i)`case-class是否使用反射?
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, v2: Int, v3: Any)
defined class Foo
scala> val bar = Foo("Moin", 77, null)
bar: Foo = Foo(Moin,77,null)
scala> bar.productElement(0)
res4: Any = Moin
scala> bar.productElement(1)
res5: Any = 77
scala> bar.productElement(2)
res6: Any = null
伟大的答案!而且,'-print'选项看起来非常有用,至今我都不知道。谢谢史蒂夫! – 2010-10-30 08:27:57