Scala,Maven和预处理器

我知道Java中预处理器和宏的所有哲学论据。 我不同意,因为有些人可能滥用语言function,所以应该排除它。

我想在我的Java和Scala代码中包含__FILE____LINE__宏以实现高效的日志记录。 由于运行时性能影响,任何使用Exception都是不可接受的。 那些认为可以在“生产代码”中关闭日志记录的人应该听取Brian Kernighan的建议:

删除错误消息“现在程序正在运行”就像在地面上戴着降落伞一样,但是一旦你在空中就把它取下来。

这些宏是否有可能使其成为语言? 如果没有,有没有办法使用Maven运行像m4这样的预处理器?

谢谢。

更新 @ralph嗯,这是2年多以前的一个问题,但由于我对__LINE____FILE__有同样的需求,你提到了SCALA; 以下是我使用Scala宏的一些想法(截至v2.10.0-RC1

 def $currentPosition:String = macro _currentPosition; def _currentPosition(c:Context):c.Expr[String]={ import c.universe._; val pos = c.enclosingPosition; c.Expr(Literal(Constant( s"${pos.source.path}: line ${pos.line}, column ${pos.column}" ))) } 

编译时对宏进行求值, $currentPosition将替换为描述其在源代码中的位置的文字字符串。 例如,在第13行放入println ,它显示:

 /sandbox/tmp_juno_workspace2/LogMacro_Test/src/test/Trial.scala: line 13, column 15 

我没有广泛地使用这些机制,但通过调整这个东西,可以开发他需要的日志记录function(我应该补充说,编写宏可能很困难 – 这对我来说!)。

恕我直言,实现这一目标的“正确”方法是编写一个编译器插件来执行替换,但它真的值得付出这么多努力吗?

无论如何,测井应该是一个贯穿各领域的问题。 可以通过方面做你想做的事。

您可以使用编译器API执行此操作,但要小心。 注释处理器/编译器插件的“规则”声明它们不应该修改正在生成的类。 Sun / Oracle可以随时强制执行此操作。

现在,请访问http://projectlombok.org 。 它使用编译器API生成getter,setter等。 它们具有可用作模型的源代码,或者您可以为它们提供处理程序。

你可能会做类似以下的事情:

 public class Foo { @FileName private static String fileName; @LineNumber private static int lineNumber; ... public void foo() { log(fileName, lineNumber, "some message"); } } 

然后让注释处理器将fileName和lineNumber引用更改为实际的文件/行。

请注意,这可能会破坏以后的JDK版本。 我不知道Sun / Oracle是否会实际执行“不要修改正在生成的类”规则,但他们可以。