我正在编写一个需要获取构造函数参数默认值的宏。 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
方法。但这不够优雅。如果我知道编译器将生成某种方法,我该如何在编译的代码中访问它?
答案 0 :(得分:2)
// 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