Strange behavior with reflection in Scala

白昼怎懂夜的黑 提交于 2019-12-08 19:38:07

问题


I was trying to follow an example from another question, and I came upon something I cannot explain:

scala> import scala.reflect.runtime.{currentMirror => m}
import scala.reflect.runtime.{currentMirror=>m}

scala> m.mkToolBox()
<console>:12: error: value mkToolBox is not a member of reflect.runtime.universe.Mirror
              m.mkToolBox()
                ^

scala> import scala.tools.reflect.ToolBox
import scala.tools.reflect.ToolBox

scala> m.mkToolBox()
res3: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@225765b0

How come mkToolBox is not a member of m before importing ToolBox, but is afterwards?


回答1:


ToolBox is an implicit class that pimps mkToolBox onto Mirror. Same story with Eval, which pimps eval.




回答2:


If I examine it with reify, I see this:

scala> reify{ m.mkToolBox() }.tree
res4: reflect.runtime.universe.Tree = 
{
  val qual$1 = scala.tools.reflect.`package`.ToolBox(scala.reflect.runtime.`package`.m);
  val x$1 = qual$1.mkToolBox$default$1;
  val x$2 = qual$1.mkToolBox$default$2;
  qual$1.mkToolBox(x$1, x$2)
}

That means there's a method call to a function named ToolBox inside the package object scala.tools.reflect. It is not an object, because reify would expose the apply method.

So, even though the API Docs for the Compiler do not show anything but the trait on the left side, if you look at the package you'll see an implicit method definition.

PS: Yes, this was a real question. The thought of an uppercase-starting method with the same name of a trait did not occur to me, until I thought of reifying the thing to get the tree.



来源:https://stackoverflow.com/questions/11283204/strange-behavior-with-reflection-in-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!