idea 自动生成方法注释
宏注释是一种新型的宏,它是即将发布的Scala 2.11版本中包含的候选对象之一(另请参见下面的Eugene评论)。 但是,由于最近发布了Macro Paradise Scala 2.10编译器插件 ,并且在编译器/ SBT设置中具有附加选项,因此您可以立即使用它们,同时仍在运行时使用稳定的Scala版本。
手册中提到的宏注释用例之一是编译时AOP。 我决定尝试实现类似的方法,但是从一开始就简单一些:自动生成委托方法(装饰器模式/代理模式)。 实际上,几年前,使用编译器插件( autoproxy插件 )也做了类似的工作。 另一个动机是, Łukasz最近在我们的技术室中问Scala是否具有此确切功能–我应该说“尚未”,而不是说“否”。
POC的结果可在GitHub的scala-macro-aop存储库中找到: https : //github.com/adamw/scala-macro-aop 。 如果您有SBT,则只需从SBT控制台调用run
即可进行实施。
它是如何工作的? 假设我们有一个接口Foo
其中包含三个方法(具有非常原始的名称: method1
, method2
和method3
),每个方法都有一些参数。 我们有一个默认的实现:
trait Foo {
def method1(param1: String): Int
def method2(p1: Int, p2: Long): Float
def method3(): String
}
class FooImpl extends Foo {
def method1(param1: String) = param1.length
def method2(p1: Int, p2: Long) = p1 + p2
def method3() = "Hello World!"
}
现在,我们想为Foo
实例创建一个包装器,它将所有方法调用委托给给定实例,除非该方法在包装器中定义。
传统的解决方案是手动为每种方法创建一个委托,例如:
class FooWrapper(wrapped: Foo) extends Foo {
def method1(param1: String) = wrapped.method1(param1)
def method2(p1: Int, p2: Long) = wrapped.method2(p1, p2)
def method3() = wrapped.method3()
}
但这是很多工作。 使用@delegate
宏,委托方法现在将在编译时自动生成! 也就是说,包装器现在变为:
class FooWrapper(@delegate wrapped: Foo) extends Foo {
// method1, method2 and method3 are generated at compile time
// and delegate to the annotated parameter
}
如果我们要实现一些方法怎么办? 该宏将仅生成丢失的宏:
class FooWrapper(@delegate wrapped: Foo) extends Foo {
def method2(p1: Int, p2: Long) = p1 - p1
// only method1 and method3 are generated
}
由于实现只是一个POC,因此仅在简单情况下(即具有单个参数列表,没有类型参数且方法未重载的方法)才能使用。 再加上宏的代码,例如,“尚未完善”。
如前所述,该代码位于GitHub: https : //github.com/adamw/scala-macro-aop ,可通过Apache2许可获得。
idea 自动生成方法注释