Scala:获取param默认值:无法在companion对象中访问`apply $ default $ i`

时间:2015-02-25 11:57:34

标签: scala reflection scala-macros

我正在编写一个需要获取构造函数参数默认值的宏。 This answer表明可以通过访问伴随对象上编译器生成的方法apply$default$i来完成此操作,其中apply是构造函数的名称,i是1基于参数索引。

但是,如果从伴随对象本身内部调用宏,则这不起作用。据推测,伴随对象中的代码的类型检查发生在编译器生成apply$default$i方法之前。

此代码有效(无论是手动编写还是由宏生成):

case class C(i: Int = 1)
object C 
def x: Int = C.apply$default$1

但这并不是:

case class C(i: Int = 1)
object C {
  def x: Int = C.apply$default$1
}

scalac抱怨value apply$default$1 is not a member of object C

我需要从伴侣对象中调用宏,因为宏定义了一个隐式类型类实例。

我可以生成代码,在运行时使用反射来访问apply$default$i方法。但这不够优雅。如果我知道编译器将生成某种方法,我该如何在编译的代码中访问它?

2 个答案:

答案 0 :(得分:2)

Here is the relevant comment.

  // Default getters of constructors are added to the companion object in the
  // typeCompleter of the constructor (methodSig).

也许您的宏可以替换您自己的名字in the attachment来同时输入您的其他方法。

答案 1 :(得分:1)

嗯,明显的解决方法是生成在随播对象之外调用apply$default$1的方法,并在里面调用此方法的方法:

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class C(i: Int = 1)
object C { def y: Int = x }
def x: Int = C.apply$default$1

// Exiting paste mode, now interpreting.

defined class C
defined module C
x: Int

scala> C.y
res6: Int = 1