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!

这一直有效,直到我今天早上尝试更新到Scala2.10.2:

scala> StupidUnderscore.`_`
<console>: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助手解决方案更可怕。

由于backtick是Java interop对标识符(例如Thread.yield())的机制,我怀疑还有其他方法不使用反射。我认为(在修复错误之前)最好的办法是用Java编写一个静态助手方法来访问_

我知道这完全是荒谬的,但它可能仍然比使用反射更好。他们用那个补丁破坏了Java互操作,所以他们最终必须解决这个问题。然而,在他们这样做之前,我认为它只是坏了。

最新更新