转义Scala中Java互操作性的下划线
假设我有一些Scala代码调用一个使用_
作为标识符的Java库(我这样做很长)。 这是一个简化的例子:
public class StupidUnderscore { public static String _() { return "Please give me a real name!"; } }
没问题,对吧? 逃避吧:
scala> StupidUnderscore.`_` res0: String = Please give me a real name!
这一直有效,直到今天早上我尝试更新到Scala 2.10.2:
scala> StupidUnderscore.`_` :1: error: wildcard invalid as backquoted identifier StupidUnderscore.`_` ^
这是由于2.10.1中出现的更改并修复了此问题 。 从提交消息:
禁止
_
作为标识符,它只能带来不良。
嗯,当然,但我不知道为什么这意味着我无法摆脱它 – 我认为这是反引号的意思。
我是否必须编写Java包装器才能使其工作? 还有其他方法可以在Scala中引用Java库的_
方法吗?
作为脚注,我已经确认可以在不编写任何新Java的情况下解决此问题:
object AwfulMacroHack { import scala.language.experimental.macros import scala.reflect.macros.Context def _impl(c: Context) = { import c.universe._ c.Expr[String]( Select(Ident(newTermName("StupidUnderscore")), newTermName("_")) ) } def `I'm not named _!` = macro _impl }
然后:
scala> AwfulMacroHack.`I'm not named _!` res0: String = Please give me a real name!
不过,我不确定这是否比Java帮助程序解决方案更糟糕。
由于反引号是Java互操作标识符的机制( 例如Thread.yield()
),我怀疑没有使用Reflection的另一种方法。 我想说你最好的选择(直到错误修复)是用Java编写一个静态辅助方法来访问_
。
我知道这完全是荒谬的,但它可能仍然比使用reflection更好。 他们打破了Java补丁,所以他们最终必须解决这个问题。 然而,在他们这样做之前,我认为它刚刚破裂。